Dart 迟发和终发可以一起使用吗?

Dart 迟发和终发可以一起使用吗?,dart,dart-null-safety,Dart,Dart Null Safety,我现在正在尝试NNBD,我想知道您是否可以同时使用新关键字late和final 据我所知,late属性可以在任何地方设置。您基本上是在告诉分析器,它在使用时不会为空。 我认为在某些情况下这有点危险 因此,我想知道是否可以在NNBD中添加一个late final,这将告诉分析器必须在类构造函数中初始化属性 有一个类似的问题,但我想当时没有零安全: 简短回答:不,您将无法从分析仪获得任何帮助 从nnbd语言规范: 如果顶级变量或静态变量具有 不可为null的类型没有初始值设定项表达式,除非变量为

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

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

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

有一个类似的问题,但我想当时没有零安全:

简短回答:不,您将无法从分析仪获得任何帮助


从nnbd语言规范:

如果顶级变量或静态变量具有 不可为null的类型没有初始值设定项表达式,除非变量为 用后期或外部修饰语标记的

如果类声明声明了实例变量,则为错误 具有潜在不可为null的类型且没有初始值设定项表达式, 该类有一个生成构造函数,其中变量不是 通过初始化形式或初始值设定项列表项初始化, 除非变量标记为延迟、抽象或外部 修饰语

latefinal int foo
基本上关闭
foo
的空感知。这似乎相当于在Swift中使用隐式未包装选项,如果您熟悉这一点,这可能是危险的

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

设D为
late
final
局部变量声明,名为
v
。如果先前已将值分配给
v
,则将值分配给
v
是一个运行时错误,抛出
LateInitializationError
的实例


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

您可以声明
late final
变量

如果使用初始值设定项声明它,
latefinal foo=computeSomething(),则它是一个惰性最终变量。无法为变量赋值,但只有在第一次读取变量时才计算其值。(根据我的经验,对于局部变量来说,这从来都不是正确的选择,即使语言允许。如果你关心局部变量的延迟初始化,你也几乎总是想知道它是否已初始化,而延迟变量并没有给你这些信息。同样令人困惑的是,代码的执行是无序的,并且它不允许您在初始值设定项表达式中使用
wait

如果在没有初始值设定项的情况下声明一个
late final
变量,则允许对该变量写入一次。由于变量
很晚
,编译器不会在编译时抱怨赋值,除非它绝对确定您已经分配了变量,并且仅当它是局部变量时(因为这是编译器尝试跟踪赋值的唯一变量)

如果没有初始值设定项的
late final
变量是类的实例成员,这意味着类接口有一个setter。在公开类的公共API中的
后期final
变量时,需要非常非常小心。(请阅读:不要这样做!)

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

您可以在初始化
AnimationController
时看到此模式常用

class\u MyState使用SingleTickerProviderStateMixin扩展状态{
后期最终动画控制器_控制器;
@凌驾
void initState(){
super.initState();
_控制器=动画控制器(vsync:this);
}
}

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

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

  int get calculate => ...;
}