可以将后期和最终一起使用吗?

问题描述

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

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

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

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

解决方法

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

如果使用初始化器late final foo = computeSomething();声明 ,则它是一个惰性的最终变量。您不能分配给变量,但仅在首次读取变量时才计算其值。 (根据我的经验,即使语言允许,这也不是 local 的正确选择。如果您关心局部变量的延迟初始化,那么您几乎总是想知道 是否已初始化,并且惰性变量没有为您提供该信息,也使代码按顺序执行混乱,并且不允许您在其中使用await初始化表达式)。

如果在没有初始化程序的情况下声明late final变量,则可以一次写入变量。因为变量是late,所以除非绝对确定您已经分配了变量,并且只有在它是局部变量的情况下,否则编译器才会抱怨编译时的赋值(因为这是唯一的变量)。编译器尝试跟踪分配给的目标。)

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

最好在内部使用后期变量并保护对字段的访问,因此可以确保没有人两次分配变量。如果最终变量分配了两次,则其最终目标是不抛出异常。永远不要分配两次。出于某种原因,允许编译器知道的编译器无法理解的变量,该变量仅分配一次。因此,仅允许访问后期的最终变量以编写知道该原因并保持不变的代码。

,

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


根据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为名为late的{​​{1}}和final局部变量声明。如果先前已将值分配给v,则会抛出LateInitializationError实例,并向v分配值,这是运行时错误。

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

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

,

是的!

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

AnimationController

你可以使用它进行延迟初始化,例如:

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

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

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...