下面在最后一行给出了一个运行时错误,但为什么我没有收到编译时错误?
为什么会这样?fnSub
(最后一行(接受一个类型的Sub
,但这里我传递给它一个类型Parent
,它进行编译。好吧,我确实得到了一个运行时错误,但我认为这应该会给我一个编译时错误。这是Dart中的一个错误,还是我误解了类型系统的局限性,或者我只是疯了?
class Parent {}
class Sub implements Parent {
String get blah => "blah";
}
String fnSub(Sub sub) => sub.blah;
String aProblem(Parent parent) => fnSub(parent);
https://dartpad.dev/acd2767cd42371deae0644fa66e8c602
问题是默认情况下在Dart中启用implicit-casts
,这是一项功能,旨在通过在代码库中自动添加类型强制转换,使处理Dart中的类型变得更容易。
当NNBD(默认情况下不可为null(出现时,此功能将不再可用,而implicit-dynamic
也将消失。现在可以按照本指南禁用这两项功能:https://dart.dev/guides/language/analysis-options#enabling-附加类型检查
就我个人而言,我认为大多数项目都应该禁用这两个功能,因为我在Stackoverflow上看到很多人对Dart对这些类型的处理感到困惑。所以我等不及NNBD了,这样我们就可以在Dart中获得更清晰的类型体验。希望分析器的错误对大多数人来说足够清楚,这样他们就不需要得到帮助。
如果禁用implicit-casts
,代码将在以下行失败:
String aProblem(Parent parent) => fnSub(parent);
有了这个错误:
error - The argument type 'Parent' can't be assigned to the parameter type 'Sub'. - binstackoverflow.dart:9:41 - argument_type_not_assignable
如果你想用Dartpad进行测试,你可以在下一个Dart版本的测试版上尝试以下版本,该版本启用了零安全(因此没有implicit-casts
(:https://nullsafety.dartpad.dev/