当一个方法被赋予一个父类来代替它的子类时,Dart中没有编译时错误



下面在最后一行给出了一个运行时错误,但为什么我没有收到编译时错误?

为什么会这样?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/

相关内容

最新更新