list - 在 Dart 中,List.from 和 .of 以及 Map.from 和 .of 有什么区别?
问题描述
List.from
在 Dart 中, andList.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 中被具体化,你不能使用强制转换或原始类型来更改列表/映射类型?
解决方案
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>
or结束Map<dynamic, dynamic>
。
在 Dart 2 中,类型dynamic
从顶部(Object)和底部(null)类型更改为仅作为顶部类型。因此,如果您List<dynamic>
在 Dart 1 中意外创建了 a ,您仍然可以将其传递给需要 a 的方法List<String>
。但在 Dart 2List<dynamic>
中几乎与 相同List<Object>
,所以这会失败。
如果您使用 Dart 2,则应始终使用这些 API 的类型化版本。为什么旧的仍然存在,那里的计划是什么?我真的不知道。我猜想随着时间的推移,它们将与 Dart 1 的其余部分一起被淘汰。
推荐阅读
- docker - DbContext.Database.Migrate() 未向后端提供密码
- python - 如何从循环内部 1 到 1 显示列表元素
- java - 删除多个文件java时progressBar不增加
- python - 如何修复错误的 nginx 重定向
- python - Python CancelledError 与异步队列
- django - 如何使用延迟加载且异步的异步中间件在 Django Request 对象上添加属性?
- c# - 使用 TSQL 或 Azure API C# 在弹性池中添加和删除 Azure 数据库到故障转移组
- flutter - 如何使用 Riverpod 的 statenotifier 处理表单?
- algorithm - 最快的字符串过滤算法
- kubernetes - K8s:如何在同一个节点内部署多个 Django 服务