【问题标题】:Lazy loading with Dart null-safetyDart 空安全的延迟加载
【发布时间】:2021-03-16 18:59:33
【问题描述】:

我正在尝试将一些代码迁移到启用 null 安全性的 Dart 2.12,但在找到迁移具有延迟加载/缓存值的方法的好方法时遇到了问题。

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

class MyObject {
  // ...
}

MyObject? _cachedValue;

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

2021 年 3 月 17 日更新

根据stephen 的回答和Mattia 的评论,我现在正在使用:

class MyObject {
  // ...
}

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

【问题讨论】:

  • 使用 nnbd 进行延迟初始化,您可以使用 late final 例如。 late final cachedVaue = getValue()getValue 只会在第一次调用 cachedValue 时调用一次。

标签: dart dart-null-safety


【解决方案1】:

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

 late MyObject _cachedValue;

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

如果合适的话,您也可以考虑使用占位符值。

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

编辑:Irn 的回答也不错。 ??= 操作符让我忘记了,即使我也使用它。

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

【讨论】:

    【解决方案2】:

    你必须使用该语言的 null 安全特性来获得漂亮的 null 安全代码。

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

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

    (我也会在 null 安全性之前这样写,这是延迟初始化使用 null 表示未初始化的变量的惯用方式。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-07
      • 2014-01-31
      • 2017-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-25
      • 2020-08-20
      相关资源
      最近更新 更多