问题描述
我目前正在尝试NNBD,我想知道您是否可以同时使用新关键字late
和final
。
据我了解,可以在任何地方设置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中使用隐式解包的可选选项,如果您熟悉的话,这可能很危险。
除此之外,静态分析器不会警告您有关尝试重置late final
的信息。
让D为名为
late
的{{1}}和final
局部变量声明。如果先前已将值分配给v
,则会抛出LateInitializationError
实例,并向v
分配值,这是运行时错误。
使用v
意味着您需要确切地知道何时初始化和使用事物。
是的!
您可以看到初始化 Fraction
时常用的这种模式。
AnimationController
你可以使用它进行延迟初始化,例如:
class _MyState extends State<MyPage> with SingleTickerProviderStateMixin {
late final AnimationController _controller;
@override
void initState() {
super.initState();
_controller = AnimationController(vsync: this);
}
}