在 kotlin 中,我们可以检查“late”类型变量是否已初始化,如下所示
lateinit var file: File
if (this::file.isInitialized) { ... }
是否可以在 Dart 中做类似的事情..?
不幸的是这是不可能的。
来自文档:
如果需要检查后期变量是否已初始化,请避免使用它们。
Dart 无法判断延迟变量是否已初始化或 分配给。如果您访问它,它会立即运行 初始化器(如果有的话)或抛出异常。有时你有 某些延迟初始化的状态可能比较适合, 但您还需要能够判断初始化是否已 还发生了。
尽管您可以通过将状态存储在 Late 变量并有一个单独的布尔字段来跟踪是否 变量已经设置,这是多余的,因为 Dart 内部 保持后期变量的初始化状态。相反,它是 通常更清晰,使变量非延迟且可为空。那你 可以通过检查null来查看变量是否已经初始化。
当然,如果 null 是变量的有效初始化值,那么 有一个单独的布尔字段可能确实有意义。
我从不同 dart 维护者的建议中得出的一些技巧以及我的自我分析:
late
使用提示:late
修饰符。late
修饰符,仅用于私有变量(以 _
为前缀)。初始化的责任不应委托给 API 用户。 编辑:正如Irhn提到的,这条规则对于没有初始化表达式的late final
变量才有意义,它们不应该是公共的。否则,存在公开 late
变量的有效用例。请参阅他的描述性评论!late
变量。
在无法访问的代码场景中初始化 late
late
if
子句中初始化,但else
中没有初始化,反之亦然。一些控制流短路/提前退出阻止执行到达late
享受吧!
来源:
import 'dart:async';
import 'package:flutter/foundation.dart';
class Late<T> {
ValueNotifier<bool> _initialization = ValueNotifier(false);
late T _val;
Late([T? value]) {
if (value != null) {
this.val = value;
}
}
get isInitialized {
return _initialization.value;
}
T get val => _val;
set val(T val) => this
.._initialization.value = true
.._val = val;
}
extension LateExtension<T> on T {
Late<T> get late => Late<T>();
}
extension ExtLate on Late {
Future<bool> get wait {
Completer<bool> completer = Completer();
this._initialization.addListener(() async {
completer.complete(this._initialization.value);
});
return completer.future;
}
}
使用 isInitialized 属性创建后期变量:
var lateString = "".late;
var lateInt = 0.late;
//or
Late<String> typedLateString = Late();
Late<int> typedLateInt = Late();
并像这样使用:
print(lateString.isInitialized)
print(lateString.val)
lateString.val = "initializing here";
甚至你可以等待这个类的初始化:
Late<String> lateVariable = Late();
lateTest() async {
if(!lateVariable.isInitialized) {
await lateVariable.wait;
}
//use lateVariable here, after initialization.
}
我们有一个实例,如果小部件加载失败,则它会被释放,并且包含一个在加载时填充的后期控制器。由于控制器为空,处置失败,但这是控制器可以为空的唯一情况。我们将 dispose 包装在 try catch 中来处理这种情况。
File? file;
File myFile;
if (file == null) {
file = File();
}
myFile = file!;
请注意
myFile = file!;
中的感叹号,这会将
File?
转换为 File
。import 'dart:io';
void main() {
example(false);
}
void example(bool initialize) {
late final File file;
bool check = false;
if (initialize) {
file = File("test.txt");
}
try {
// ignore: unnecessary_type_check
check = file is File;
} catch (e) {
// print(e);
}
if (check) {
print("file is defined");
} else {
print("file is not defined");
}
}