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

Mar*_*rcG 6 generics dictionary types list 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);
Run Code Online (Sandbox Code Playgroud)

差异与仿制药有关吗?也许.from工厂允许您更改列表的类型,而工厂.of却不允许?我来自Java背景,可以使用类型擦除,也许在Dart中对类型进行了归类化,并且您不能使用强制类型转换或原始类型来更改列表/地图类型?

Jon*_*ams 9

fromof方法之间的重要区别在于,后者具有类型注释,而前者则没有。由于对Dart泛型进行了归一化并且对Dart 2进行了强类型化,因此这是确保List/Map正确构造Dart的关键:

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
Run Code Online (Sandbox Code Playgroud)

并确保正确推断类型:

var foo = new List.from(<int>[1, 2, 3]); // List<dynamic>
var bar = new List.of(<int>[1, 2, 3]); // List<int>
Run Code Online (Sandbox Code Playgroud)

在Dart 1中,类型是完全可选的,因此许多API没有类型化或部分类型化。 List.from并且Map.from是很好的例子,由于Iterable/Map传递到他们没有一个类型参数。有时Dart可以弄清楚该对象的类型应该是什么,但是有时它只是以List<dynamic>or 结束Map<dynamic, dynamic>

在Dart 2中,类型dynamic从顶部(对象)类型和底部(空)类型更改为仅顶部类型。因此,如果您是List<dynamic>在Dart 1中意外创建的,则仍可以将其传递给需要的方法List<String>。但是在Dart 2中,List<dynamic>它几乎与相同List<Object>,因此这将失败。

如果您使用的是Dart 2,则应始终使用这些API的类型化版本。为什么旧的仍然存在,那里有什么计划?我真的不知道 我猜想随着时间的推移,它们将与Dart 1的其余部分一起逐步淘汰。

  • 然后应更新方法docs。完全不清楚。谢谢。 (2认同)

Cop*_*oad 5

List.of()toList()

它们用于创建与原始列表类型相同的新列表,但List.of()可用于向上转换:

var ints = <int> [0];
var newList1 = ints.toList(); // List<int>
var newList2 = List<num>.of(ints); // List<num>
Run Code Online (Sandbox Code Playgroud)

您还可以通过执行以下操作来复制列表:

var newList3 = [...ints]; // List<int>
var newList4 = [for (var v in ints) v]; // List<int>
Run Code Online (Sandbox Code Playgroud)

List.from()

如果您想要向下转型,请使用此选项,因此子类型是超类型的类型很重要。

var ints = List<int>.from(<num>[0, 1]); // Good as all elements are of type `int`
var ints = List<int>.from(<num>[0, 1.5]); // Bad as some elements are of type `double`
Run Code Online (Sandbox Code Playgroud)