flutter - 后期实例字段是否在构造函数中延迟初始化?
问题描述
我了解late
初始化程序,即直接具有初始化分配的声明,是懒惰地执行的:
class Foo {
late final word = calculateWord(); // Will be initialized lazily.
late final sentence; // Will not be initialized lazily.
void init() {
sentence = calculateSentence(); // This is immediately executed, i.e. before sentence is accessed.
}
}
但是,我想知道的是该行为如何映射到构造函数。我会假设该变量在构造函数中被延迟初始化,因为实例字段随后与那些直接通过赋值具有初始值设定项的字段同时被赋值。
但是,我还假设构造函数主体不会延迟初始化late
实例字段。
那么以下哪些成员被延迟初始化(如果有的话)?
class Baz {
Baz(
// Implicit assignment by the caller.
this.assignmentInConstructor,
) : assignmentInInitializerList = calculate() {
assignmentInConstructorBody = calculate();
}
late final int assignmentInConstructor; // I expect this to be lazily initialized.
late final int assignmentInInitializerList; // I expect this to also be lazily initialized.
late final int assignmentInConstructorBody; // I expect this to not be lazily initialized.
}
解决方案
没有一个是懒惰的
只有在声明late
发生赋值时,修改的字段才会变得懒惰。
这也意味着以下情况是正确的:
void main() {
late final value1 = calculate(); // This is initialized lazily.
late final value2;value2 = calculate(); // This is not initialized lazily.
}
只有通过添加;value2
,我将赋值与声明分开,这使它不再懒惰。
实例字段
因此,在构造函数中任何位置初始化的所有实例字段都不会被延迟初始化。相反,它们在被访问之前被初始化。
演示
void main() {
// Construct the object first.
final baz = Baz(calculate('assignmentInConstructor'));
// Call access to access the late variables and initialize them if they are lazy.
baz.access();
}
class Baz {
Baz(
// Implicit assignment by the caller.
this.assignmentInConstructor,
) : assignmentInInitializerList = calculate('assignmentInInitializerList') {
assignmentInConstructorBody = calculate('assignmentInConstructorBody');
}
late final int
assignmentInConstructor; // I expect this to be lazily initialized.
late final int
assignmentInInitializerList; // I expect this to also be lazily initialized.
late final int
assignmentInConstructorBody; // I expect this to not be lazily initialized.
void access() {
print('access');
print('$assignmentInConstructor'
'$assignmentInInitializerList'
'$assignmentInConstructorBody');
}
}
int calculate(String message) {
print('calcuate $message');
return 0;
}
执行main
产生以下输出:
calcuate assignmentInConstructor
calcuate assignmentInInitializerList
calcuate assignmentInConstructorBody
access
000
这意味着所有三个实例字段,无论它们在构造函数中的哪个位置被初始化,都不会被延迟初始化。它们都是在访问之前计算出来的。
您可以在此 DartPad 演示中亲自尝试。
推荐阅读
- snipcart - Snipcart:关闭地址字段中的自动完成功能
- flutter - 尝试在颤振中进行改造并在制作restclient时出错
- android - 无法从库模块中引用 xml 中的样式和字体资源
- python - 一个文件中的全局变量在另一个文件中未定义
- php - 从 pdf 创建缩略图
- php - 带有文件名的Htaccess重定向查询字符串?wordpress 干扰
- c++ - 如何使用 std::vector 更改缓冲区数据?
- javascript - React hooks 回调引用模式
- python-3.x - 根据列表的值过滤python3中的熊猫数据框
- jquery - 单击时自动选择文本