带有 Dart 空安全的延迟加载

Lazy loading with Dart null-safety

我正在尝试将一些代码迁移到启用空安全的 Dart 2.12,但在寻找迁移具有惰性 loaded/cached 值的方法的好方法时遇到问题。

Dart 2.12 将不会编译以下代码,除非我将 getValue() 的 return 类型从 MyObject 更改为 MyObject?。但是 getValue() 永远不会 return null.

class MyObject {
  // ...
}

MyObject? _cachedValue;

MyObject getValue() {
  if (_cachedValue == null) {
    _cachedValue = MyObject();
    // some heavy computing...
  }
  return _cachedValue;
}

更新时间 2021-03-17

根据stephen and the comment by Mattia的回答我现在使用:

class MyObject {
  // ...
}

MyObject _computeValue() {
  MyObject obj = MyObject();
  // some heavy computing...
  return obj;
}
late final MyObject cachedValue = _computeValue();

如果你能确保 _cachedValue 在读取之前被初始化,那么你可以使用 late 关键字,它说“这最终会有一个值,然后永远不会为空. 同时,我要确保在它具有值之前我不会访问它

 late MyObject _cachedValue;

在用值初始化之前访问 late 变量将引发错误。

或者,如果合适,您可以考虑使用占位符值。

最后,您可以使用 ! 断言您确定某个值不为空。在您的情况下,这可能是最合适的解决方案。在 getValue() 中你会 return _cachedValue!; 而不是 return _cachedValue;

编辑:Irn 的回答也很好。尽管我也使用 ??= 运算符,但它还是让我忘记了。

除此之外,您还有一个可为空的值,因此您的 getter 必须 return 一个 MyObject?

您必须使用该语言的空安全功能才能获得漂亮的空安全代码。

在这种情况下,我将 getValue 重写为:

MyObject getValue() => _cachedValue ??= MyObject();

(在空安全之前我也会这样写,这是懒惰初始化变量的惯用方式,它使用 null 表示未初始化)。