http://www.dartlang.org/docs/spec/dartLangSpec.pdf
Dart 的语言规范在下面提到
Dart 支持基于接口类型的可选类型。由于泛型类型的协变,类型系统不健全。这是一个深思熟虑的选择(无疑是有争议的)。经验表明, 泛型的健全类型规则违背了程序员的直觉。这是 ..
- 有人可以进一步详细说明类型系统不健全的原因吗?
- 当 Dart 语言规范的作者说泛型的健全类型规则违背直觉时,他们在想什么?
http://www.dartlang.org/docs/spec/dartLangSpec.pdf
Dart 的语言规范在下面提到
Dart 支持基于接口类型的可选类型。由于泛型类型的协变,类型系统不健全。这是一个深思熟虑的选择(无疑是有争议的)。经验表明, 泛型的健全类型规则违背了程序员的直觉。这是 ..
从吉拉德布拉查 [1]:
你可以编写一个工具,对这些事情大发雷霆,但你不能做的是阻止人们运行他们的程序。
或者,换句话说[2]:
问题在于,对于大多数程序员来说,完全而明确地表达类型流比编写传递值并在发生时处理运行时类型错误的代码更加困难。为这种难度差异选择的词是后者比前者更“直观”——我不认为这是一个特别糟糕的词选择。这种现象是近年来动态语言变得更加流行的最大原因之一,它拒绝指定静态类型的复杂性。
就像还有另一个三角形权衡:富有表现力、声音、简单:为您的类型系统选择任意两个。几乎每个人都不愿意放弃表现力——现代软件中编织的对象图确实可以很纠结——而任何希望获得大规模成功的语言都不能一开始就相当简单。所以他们放弃了一些(静态类型)健全性的衡量标准,并期望在调试和测试期间出现大量运行时类型错误。
[1] http://blog.sethladd.com/2011/11/transcription-of-quick-tour-of-dart-by.html
当 Dart 语言规范的作者说泛型的健全类型规则违背直觉时,他们在想什么?
看看这个问题右侧的相关问题。我懂了:
List<Number>
不是一个子类型List<Object>
?List<Derived>
给 a List<Base>
?list<MyClass>
到List<object>
?Animals[] animals = new Cat[5]
编译,但List<Animal> animals = new List<Cat>()
不编译?虽然协方差并不可靠(对于许多可变类型),但这是许多程序员在第一次开始使用泛型类型时直观地期望的行为。
更具体地说,就不健全而言,泛型类型是协变的。因此,可以将字符串列表传递给需要对象列表的东西。这不是类型安全的,因为期望 Object 列表的东西可能会尝试向 List 中添加一些不是 String 的东西。但是告诉人们当你有 B 作为 A 的子类,但 Collection<B> 不是 Collection<A> 的子类型时,这是非常不直观的。