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

当给方法一个父类代替它的子类时,Dart中没有编译时错误,dart,Dart,下面在最后一行给出了一个运行时错误,但是为什么我没有收到编译时错误 为什么会这样fnSub(最后一行)接受一种类型的Sub,但在这里我向它传递一种类型的Parent,然后它编译。好的,我确实得到了一个运行时错误,但我认为这应该给我一个编译时错误。这是Dart中的一个bug,还是我误解了类型系统的局限性,还是我疯了 class Parent {} class Sub implements Parent { String get blah => "blah"; }

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

为什么会这样
fnSub
(最后一行)接受一种类型的
Sub
,但在这里我向它传递一种类型的
Parent
,然后它编译。好的,我确实得到了一个运行时错误,但我认为这应该给我一个编译时错误。这是Dart中的一个bug,还是我误解了类型系统的局限性,还是我疯了

class Parent {}

class Sub implements Parent {
  String get blah => "blah";
}

String fnSub(Sub sub) => sub.blah;

String aProblem(Parent parent) => fnSub(parent);

问题在于默认情况下,Dart中启用了
隐式强制转换
,这是一项功能,通过在代码库中自动添加类型强制转换,使Dart中的类型更易于处理

当NNBD(默认情况下不可为空)出现时,此功能将不再可用,
隐式动态
也将消失。按照本指南的要求,现在可以禁用这两项功能:

就我个人而言,我认为大多数项目都应该禁用这两个功能,因为我看到Stackoverflow上的很多人对Dart如何处理类型感到困惑。所以我不能等待NNBD,这样我们就可以在Dart中获得更清晰的类型体验。希望分析仪的错误对大多数人来说足够清楚,所以他们不需要得到帮助

如果禁用隐式强制转换,代码将在以下行失败:

String aProblem(Parent parent) => fnSub(parent);
有了这个错误:

错误-无法将参数类型“Parent”分配给参数类型“Sub”。-bin\stackoverflow.dart:9:41-参数类型不可分配

如果您想使用Dartpad进行测试,您可以在下一个Dart版本的beta版的基础上尝试以下版本,该版本启用了空安全(因此没有
隐式强制转换
):

我发现,如果说有一个名为“隐式强制转换”的功能已启用,则有点误导。Dart(pre-null-safety)只允许您在需要子类型的情况下使用超类型表达式,这将为子类型引入隐式向下转换。这不是一个可以启用或禁用的功能,而是语言的使用方式。如果愿意,您可以要求分析器报告此类具有隐式降级功能的有效程序的错误,但这是您将自己限制为Dart语言的一个子集,而不是语言功能。禁用下载是analyzer的一项功能。