为什么流分析在使用 bool 时不起作用?

Why flow analysis doesn't work when using bool?

void main() {
  int? foo;
  var isNonNull = foo != null;
  
  if (isNonNull) foo.isEven; // Error
}

我已经检查了 foo 并将其值存储在 isNonNull 变量中。如果范围不是本地的,我可以理解该警告。

注意:我知道我可以使用 ! bang 运算符来解决它,但为什么流分析不起作用?

您收到错误是因为流分析无法知道 isNonNull 是否会获得新值。举个例子:

final random = Random();
void main() {
  int? foo;
  var isNonNull = foo != null;
  isNonNull = random.nextBool();
  if (isNonNull) foo.isEven;
}

所以,最好用

if (foo != null) foo.isEven;

Dart 类型提升基于检查变量以特定方式支配该变量的后续使用。

因此,如果您执行 if (x != null) x.foo();,它检测到检查 x != null 为真意味着后面的 x.foo() 有效。 只有效,因为编译器也可以说服自己变量的值在检查和使用之间不会改变。

如果你引入一个额外的布尔变量,就像这里一样,那么检查就不再在分支内部执行。这并不意味着 不可能 记住 isNonNull 布尔值是真的意味着 foo 是非空的,但它得到更多 复杂。编译器现在必须确保 foo 不会更改 并且 isNotNull 不会更改。 相反,Dart 编译器会退出,它不会跟踪那种程度的复杂性。它一次仅通过 一个 变量跟踪提升。