我开始学习Dart,并在这里阅读了对其一些设计选择的评论:https://medium.com/@krossovochkin/dart-language-bad-design-chices-6e35987dc693
最后一点是关于糟糕的类型系统,作者引用了这个打印null
:的代码片段
void main() {
String s = null;
if (s is String) {
print("string");
} else if (s is Null) {
print("null");
} else {
print ("none");
}
}
is
关键字对我来说是新的,但吉拉德的《Dart编程语言》指出,is
检查的是由对象的类实现的接口,而不是对象的实际类。
然而,这对我没有太大帮助,因为我认为变量s
是String
的一个实例,因此实现了String
,但证据恰恰相反。
我发现在Dart中定义对象/变量时不需要这个类,因此我开始怀疑把这个类放在定义中是否只是一种糖,几乎没有什么功能用途。但是,对象/变量的类完全由其值决定,并且由于Dart中所有变量的默认值都是null
,因此不实现String
,而实现Null
是有道理的。是这样吗?我是基地的方式吗?也许有人能帮我好好想想。
原因是is
检查的是当前对象本身的接口,而不是对该对象的引用。因此,是的,s
可以指向String
对象,但也可以指向作为Null
实例的null:https://api.dart.dev/stable/2.7.2/dart-core/Null-class.html
由于Null
没有实现String
接口,这将返回错误的(null is String)
。文章中也提到了这一点。
本文试图关注的问题更多的是允许将String
变量设置为null
值,但Null
没有实现String
。
好吧,在未来,这个问题将通过目前正在开发的不可为null的类型来解决。当实现这一点时,您可以实际定义变量,确保值永远不会是null
。
所以我继续阅读Dart,我有了更好的理解,那就是Dart确实是可选类型的,这意味着两件事:
- 类型在语法上是可选的
- 类型对运行时语义没有影响
因此,Dart中变量的实际类型注释仅用于文档目的,不能假设类型注释为true。变量的实际类型完全由存储在该变量中的值决定,在这种情况下,它是null
。
事实上,我在示例中定义的变量不是String
变量,也不是String
接口的实现者。它只是被注释为它可能是/应该是/很可能是一个字符串。