在Dart中,List.from
和List.of
之间以及Map.from
和Map.of
之间的区别是什么?他们的文件并不完全清楚:
/**
* Creates a [LinkedHashMap] instance that contains all key/value pairs of
* [other].
*
* The keys must all be instances of [K] and the values of [V].
* The [other] map itself can have any type.
*
* A `LinkedHashMap` requires the keys to implement compatible
* `operator==` and `hashCode`, and it allows `null` as a key.
* It iterates in key insertion order.
*/
factory Map.from(Map other) = LinkedHashMap<K, V>.from;
/**
* Creates a [LinkedHashMap] with the same keys and values as [other].
*
* A `LinkedHashMap` requires the keys to implement compatible
* `operator==` and `hashCode`, and it allows `null` as a key.
* It iterates in key insertion order.
*/
factory Map.of(Map<K, V> other) = LinkedHashMap<K, V>.of;
/**
* Creates a list containing all [elements].
*
* The [Iterator] of [elements] provides the order of the elements.
*
* All the [elements] should be instances of [E].
* The `elements` iterable itself may have any element type, so this
* constructor can be used to down-cast a `List`, for example as:
* ```dart
* List<SuperType> superList = ...;
* List<SubType> subList =
* new List<SubType>.from(superList.whereType<SubType>());
* ```
*
* This constructor creates a growable list when [growable] is true;
* otherwise, it returns a fixed-length list.
*/
external factory List.from(Iterable elements, {bool growable: true});
/**
* Creates a list from [elements].
*
* The [Iterator] of [elements] provides the order of the elements.
*
* This constructor creates a growable list when [growable] is true;
* otherwise, it returns a fixed-length list.
*/
factory List.of(Iterable<E> elements, {bool growable: true}) =>
new List<E>.from(elements, growable: growable);
差异与仿制品有关吗?也许.from
工厂允许你改变列表的类型,而.of
工厂却没有?我来自Java背景,它使用类型擦除,也许类型在Dart中具体化,你不能使用强制转换或原始类型来更改列表/地图类型?
答案 0 :(得分:6)
from
和of
方法之间的重要区别在于后者具有类型注释而前者没有。由于Dart泛型被强化并且Dart 2是强类型的,因此这对确保正确构造List/Map
至关重要:
List<String> foo = new List.from(<int>[1, 2, 3]); // okay until runtime.
List<String> bar = new List.of(<int>[1, 2, 3]); // analysis error
确保正确推断出类型:
var foo = new List.from(<int>[1, 2, 3]); // List<dynamic>
var bar = new List.of(<int>[1, 2, 3]); // List<int>
在Dart 1中,类型完全是可选的,因此许多API都是无类型或部分类型的。 List.from
和Map.from
是很好的示例,因为传递给它们的Iterable/Map
没有类型参数。有时Dart可以确定该对象的类型应该是什么,但有时它最终会以List<dynamic>
或Map<dynamic, dynamic>
结束。
在Dart 2中,类型dynamic
从顶部(Object)和底部(null)类型都变为顶级类型。因此,如果您在Dart 1中意外创建了List<dynamic>
,您仍然可以将其传递给需要List<String>
的方法。但是在Dart 2 List<dynamic>
几乎与List<Object>
相同,所以这会失败。
如果您使用的是Dart 2,则应始终使用这些API的类型版本。为什么旧的仍然存在,那里的计划是什么?我真的不知道。我猜他们会随着时间的推移逐渐被淘汰,还有其他的Dart 1。