当我遇到以下代码时,我一直在Dart By Example通过Shailen Tuli的片段集合:
List<String> fruits = [
{'name': 'apple', 'selected': true},
{'name': 'banana', 'selected': true},
{'name': 'kiwi', 'selected': false}
];
请注意,fruits
被声明为List<String>
,但列表元素实际上是地图。
问题:为什么没有报告类型错误?
答案 0 :(得分:5)
如果代码示例是使用强静态类型语言编写的,则会报告错误。但 Dart 是:
考虑这个声明:
List<num> lst = [4, "ty-two"];
重要的是要理解,给定的数组文字[4, "ty-two"]
的类型为List<dynamic>
,其中dynamic
是静态类型,归因于表达式,当静态类型系统不知道它是什么时(例如,用户没有声明静态类型),或者不想打扰进行更深入的分析以找出类型可能是什么 - 就像这样的情况对于列表lst
的通用参数。
如果您声明文字列表元素的预期静态类型,静态类型系统只能指出存在类型错误:
List<num> lst = <num>[4, "tytoo"];
List<String> fruits = <Map>[{'name': 'apple', ...}, ...];
现在,在这两种情况下都会报告类型错误。在lst
的情况下,乐观系统可以轻松地告诉String
"ty-two"
永远不会是num
类型。类似的评论适用于fruits
。另一方面,如果我们有
var a = "tytoo";
List<num> lst = <num>[4, a];
使用var
声明变量有效地意味着(对于静态类型检查器)a
类型为dynamic
。因此,在lst
的分配中没有报告错误。
详情见Language Specification和这两篇(恕我直言)优秀文章;他们解释了Dart的输入,同时也涵盖了与类型系统相关的语言设计决策背后的基本原理。
-
1 https://www.dartlang.org/articles/why-dart-types/
2 https://www.dartlang.org/articles/optional-types/