简体   繁体   English

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

[英]In Dart, what's the difference between List.from and .of, and between Map.from and .of?

In Dart, what's the difference between List.from and List.of , and between Map.from and Map.of ?在 Dart 中, List.fromList.of以及Map.fromMap.of之间有什么区别? Their documentation is not totally clear:他们的文档并不完全清楚:

/**
* 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);

Is the difference related to generics?差异与generics有关吗? Maybe the .from factories let you change the type of the list, while the .of ones do not?也许.from工厂可以让你改变列表的类型,而.of不能? I come from a Java background, which works with type erasure, and maybe types are reified in Dart and you cannot use casts or raw types to change list/map types?我来自 Java 背景,它适用于类型擦除,并且可能类型在 Dart 中被具体化,并且您不能使用强制转换或原始类型来更改列表/映射类型?

The important difference between the from and of methods are that the latter have type annotations and the former do not. 之间最重要的区别fromof方法是,后者有类型的注释和以前没有。 Since Dart generics are reified and Dart 2 is strongly typed, this is key to both ensuring the List/Map is correctly constructed: 由于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

And ensuring that the types are inferred correctly: 并确保正确推断类型:

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

In Dart 1 types were completely optional, so many APIs were untyped or partially typed. 在Dart 1中,类型是完全可选的,因此许多API都是无类型或部分类型的。 List.from and Map.from are good examples, since the Iterable/Map passed into them doesn't have a type parameter. List.fromMap.from是很好的例子,因为传递给它们的Iterable/Map没有类型参数。 Sometimes Dart can figure out what the type of this object should be, but sometimes it just ended up as List<dynamic> or Map<dynamic, dynamic> . 有时Dart可以确定该对象的类型应该是什么,但有时它最终会以List<dynamic>Map<dynamic, dynamic>

In Dart 2 the type dynamic was changed from being both a top (Object) and bottom (null) type to only being a top type. 在Dart 2中,类型dynamic从顶部(Object)和底部(null)类型变为仅作为顶部类型。 Thus if you created a List<dynamic> accidentally in Dart 1 you could still pass it to a method which required a List<String> . 因此,如果您在Dart 1中意外创建了List<dynamic> ,您仍然可以将其传递给需要List<String> But in Dart 2 List<dynamic> is almost the same as List<Object> , so this would fail. 但是在Dart 2 List<dynamic>几乎与List<Object>相同,所以这会失败。

If you are using Dart 2, you should always use the typed version of these APIs. 如果您使用的是Dart 2,则应始终使用这些API的类型版本。 Why do the old ones still exist, and what are the plans there? 为什么旧的仍然存在,那里的计划是什么? I don't really know. 我真的不知道。 I would guess they would be phased out over time, along with the rest of the Dart 1. 我猜他们会随着时间的推移逐渐被淘汰,还有其他的Dart 1。

Whenever possible it is better to use collection literals now rather than the .from or .of constructors.只要有可能,现在最好使用集合文字而不是.from.of构造函数。 Apparently there are some performance benefits to this.显然,这有一些性能优势。 (See link at bottom.) (请参阅底部的链接。)

Examples:例子:

  • something.toList()
  • [...something]

Exception:例外:

  • Can use .from if you need to downcast.如果您需要向下转换,可以使用.from

If you do use them, though, you should always include the type.但是,如果您确实使用它们,则应始终包含该类型。

Source: Dart team engineer's post来源: Dart 团队工程师帖

List.of() and toList() List.of()toList()

They are used to create a new list of the same type as the original, but List.of() can be used to upcast:它们用于创建与原始列表相同类型的新列表,但List.of()可用于向上转换:

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

You can also copy a list by doing:您还可以通过执行以下操作复制列表:

var newList3 = [...ints]; // List<int>
var newList4 = [for (var v in ints) v]; // List<int>

List.from()

Use this if you want to downcast and therefore it is important that the subtype is a type of supertype.如果您想向下转换,请使用此选项,因此子类型是超类型的类型很重要。

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`

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM