【问题标题】:Can late and final be used together?late 和 final 可以一起用吗?
【发布时间】:2021-01-10 06:22:38
【问题描述】:

我现在正在尝试 NNBD,我想知道您是否可以同时使用新关键字 latefinal

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

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

有一个类似的问题,但我想当时没有空安全: Dart. Late initialize final variables

【问题讨论】:

标签: dart dart-null-safety


【解决方案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 => ...;
}

【讨论】:

    【解决方案2】:

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

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

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

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

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

    【讨论】:

      【解决方案3】:

      简短回答:不,您不会从分析仪获得任何帮助。


      来自 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 为名为 vlatefinal 局部变量声明。如果先前已将值分配给 v,则将值分配给 v 是一个运行时错误,抛出 LateInitializationError 的实例。

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

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

      【讨论】:

        猜你喜欢
        • 2013-11-01
        • 2016-02-21
        • 2016-01-31
        • 2013-06-08
        • 1970-01-01
        • 1970-01-01
        • 2021-12-23
        • 2011-10-27
        • 2017-08-11
        相关资源
        最近更新 更多