在Dart中,List.from和.of之间以及Map.from和.of之间的区别是什么?

时间:2018-05-13 20:10:36

标签: list dictionary generics types dart

在Dart中,List.fromList.of之间以及Map.fromMap.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中具体化,你不能使用强制转换或原始类型来更改列表/地图类型?

1 个答案:

答案 0 :(得分:6)

fromof方法之间的重要区别在于后者具有类型注释而前者没有。由于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.fromMap.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。