【问题标题】:Why does `if (var = null)` compile in dart?为什么 `if (var = null)` 在 dart 中编译?
【发布时间】:2018-06-27 07:57:03
【问题描述】:

我最近遇到了这个问题How do I solve the 'Failed assertion: boolean expression must not be null' exception in Flutter

问题出在哪里应该是被视为有效的无效代码。

这段代码可以概括为:

int stuff;
if (stuff = null) { // = instead of ==
}

但是为什么这段代码会编译?因为下面不会。

int stuff;
if (stuff = 42) {
}

出现以下编译错误:

条件必须具有静态类型“bool”。

因此,出于一致性,我预计 if (stuff = null) 会给出相同的错误。

【问题讨论】:

    标签: dart


    【解决方案1】:

    null 是 Dart 中 bool 变量的有效值,至少在 Dart 支持不可为空的类型之前是这样。

    bool foo = null;
    

    或者只是

    bool foo;
    

    有效。

    因此,从静态分析的角度来看,第一种情况并没有错。

    在第 2 种情况下,类型 int 是由于分配而被推断出来的,已知它不是有效的布尔值。

    bool foo = 42; 
    

    无效。

    【讨论】:

    • stuff 不是bool。而if (stuff)不起作用。所以我认为if (stuff = null) 没有理由也可以工作。我可以从技术上理解为什么。但这感觉更像是一个错误而不是一个功能。
    • bool myVar = stuff = null 也是如此。如果stuff 不是布尔值,那应该是不可能的。
    • 是的,这些都是更有趣的问题。我想我们最好等待@lrhn 得到正确的答案;-)
    • 为了记录,当前的答案是正确的。 stuff = null 的值和类型是 null,类型为 Null。您没有将 stuff 分配给任何东西。您将null 分配给两个不同的事物,无论您写foo = bar = null 还是bar = foo = null 只会改变分配的顺序,而不是分配的值(在这两种情况下都是null)。
    【解决方案2】:

    当你说var stuff; 没有初始值时,它给stuff 一个静态类型dynamic。由于dyamic 可能bool,因此将null 分配给dynamic 类型的变量是合法的,并且在条件中使用可能为空的布尔值是合法的,编译器不会不要标记这个。当你说int stuff; 时,编译器知道stuff 不可能是bool。在这种情况下报告的错误是由stuff 的静态类型引起的,而不是对null 的分配。

    编辑:从知道如何阅读规范的人那里得到真正的答案。

    赋值表达式的静态类型是赋值的右侧。所以表达式stuff = null 的静态类型为Null,可以赋值给bool

    原因是赋值的 value 是右手边,所以使用它的类型也是有意义的。这允许如下表达式:

    int foo;
    num bar;
    foo = bar = 1;
    

    【讨论】:

    【解决方案3】:

    通常的赋值操作返回它所分配的值。

    int a = 0;
      print(a = 3);//Prints 3
    

    所以,

    当 stuff = null 时,

    'stuff = null' 返回 null。 if 语句需要一个布尔值。null 是布尔值的子类型。

    if(null){}
    

    有效

    当 stuff = 42 时,

    'stuff = 42' 返回 42。if 语句需要布尔值 .42 不是布尔值的子类型。

    if(42){}
    

    无效

    【讨论】:

      猜你喜欢
      • 2017-10-12
      • 1970-01-01
      • 2012-09-07
      • 2014-04-17
      • 2013-08-18
      • 1970-01-01
      • 2010-09-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多