5

我现在正在尝试 NNBD,我想知道你是否可以使用 new 关键字latefinal一起使用。

据我了解,late可以在任何地方设置属性。您基本上是在告诉分析器使用时它不会为空。
我认为在某些情况下这有点危险。

所以我想知道你是否可以late final在 NNBD 中添加一个,这会告诉分析器该属性必须在类构造函数中初始化。

有一个类似的问题,但我想当时没有空安全性: Dart。后期初始化最终变量

4

3 回答 3

5

您可以声明一个late final变量。

如果你初始化器声明它late final foo = computeSomething();,那么它是一个惰性最终变量。您不能分配给变量,但它的值仅在第一次读取变量时计算。(根据我的经验,即使语言允许,这也不是局部变量的正确选择。如果您关心局部变量的延迟初始化,您几乎总是想知道它是否已初始化,而延迟变量不会'不给你那个信息。代码被乱序执行也令人困惑,它不允许你await在初始化表达式中使用)。

如果你声明一个没有初始化器的late final变量,你可以写一次变量。因为变量是,编译器不会在编译时抱怨分配,除非绝对确定您已经分配了变量,并且只有当它是局部变量时(因为这是编译器尝试跟踪分配的唯一变量至)。late

如果late final没有初始化器的变量是类的实例成员,这意味着类接口有一个 setter。您需要非常非常小心地late final在类的公共 API 中公开变量。(阅读:不要那样做!)

最好在内部使用后期变量并保护对字段的访问,这样可以确保没有人两次分配变量。后期最终变量的目标是如果它被分配了两次就不会抛出。它永远不应该被分配两次。它允许允许由于某种原因知道编译器无法理解的代码,该变量只分配一次。因此,只允许对知道该原因并保持不变性的代码访问后期最终变量。

于 2020-09-24T12:07:54.860 回答
1

是的!

您可以看到初始化时常用的这种模式AnimationController

class _MyState extends State<MyPage> with SingleTickerProviderStateMixin {
  late final AnimationController _controller;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(vsync: this);
  }
}

您可以将其用于延迟初始化,例如:

class Foo {
  late final int i = calculate; // Initialized only when used.

  int get calculate => ...;
}
于 2021-05-20T16:03:08.053 回答
-1

简短的回答:不,你不会从分析仪那里得到任何帮助。


来自 nnbd 语言规范:

如果具有不可为空类型的顶级变量或静态变量没有初始化表达式,则这是错误的,除非该变量被标记为后期或外部修饰符。

如果类声明声明了一个具有潜在不可空类型且没有初始化表达式的实例变量,并且该类具有生成式构造函数,其中变量未通过初始化形式或初始化列表条目进行初始化,则这是错误的,除非变量用迟到的、抽象的或外部的修饰语标记。

late final int foo;基本上关闭foo. 这似乎等同于在 Swift 中使用隐式展开的选项,如果你熟悉的话,这可能是危险的。

https://github.com/dart-lang/language/blob/master/accepted/future-releases/nnbd/feature-specification.md

除此之外,静态分析器不会警告您尝试重置late final.

令 D 为一个名为latefinal局部变量声明v。这是一个运行时错误,抛出一个 , 的实例LateInitializationError来分配一个值,v如果一个值之前已分配给v

https://github.com/dart-lang/language/blob/master/accepted/future-releases/nnbd/feature-specification.md#late-fields-and-variables

使用late意味着您需要确切知道何时初始化和使用事物。

于 2020-09-24T03:53:12.987 回答