为什么`if(var = null)`在dart中编译?

时间:2018-06-27 07:57:04

标签: dart

我最近遇到了这个问题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)出于一致性而给出相同的错误。

3 个答案:

答案 0 :(得分:3)

null是Dart中bool变量的有效值,至少直到Dart支持非空类型为止。

bool foo = null;

或者只是

bool foo;

有效。

因此,从静态分析的角度来看,在第一种情况下没有任何问题。

在第二种情况下,由于赋值,推断类型int是已知的无效布尔值。

bool foo = 42; 

无效。

答案 1 :(得分:1)

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

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

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

原因是赋值的 value 位于右侧,因此也可以使用其类型。这允许像这样的表达式:

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

答案 2 :(得分:0)

常见分配操作返回它分配的值。

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

所以

stuff = null时,

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

if(null){}

有效

当东西= 42时,

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

if(42){}

无效