如何检查 Dart 中的“late”变量是否已初始化

问题描述 投票:0回答:8

在 kotlin 中,我们可以检查“late”类型变量是否已初始化,如下所示

lateinit var file: File    
if (this::file.isInitialized) { ... }

是否可以在 Dart 中做类似的事情..?

flutter dart variables initialization
8个回答
107
投票

不幸的是这是不可能的。

来自文档:

如果需要检查后期变量是否已初始化,请避免使用它们。

Dart 无法判断延迟变量是否已初始化或 分配给。如果您访问它,它会立即运行 初始化器(如果有的话)或抛出异常。有时你有 某些延迟初始化的状态可能比较适合, 但您还需要能够判断初始化是否已 还发生了。

尽管您可以通过将状态存储在 Late 变量并有一个单独的布尔字段来跟踪是否 变量已经设置,这是多余的,因为 Dart 内部 保持后期变量的初始化状态。相反,它是 通常更清晰,使变量非延迟且可为空。那你 可以通过检查null来查看变量是否已经初始化。

当然,如果 null 是变量的有效初始化值,那么 有一个单独的布尔字段可能确实有意义。

https://dart.dev/guides/language/ effective-dart/usage#avoid-late-variables-if-you-need-to-check-whether-they-are-initialized


27
投票

我从不同 dart 维护者的建议中得出的一些技巧以及我的自我分析:

late
使用提示:

  • 如果您稍后要检查变量的初始化情况,请勿在变量上使用
    late
    修饰符。
  • 请勿对面向公众的变量使用
    late
    修饰符,仅用于私有变量(以
    _
    为前缀)。初始化的责任不应委托给 API 用户。 编辑:正如Irhn提到的,这条规则对于没有初始化表达式的
    late final
    变量才有意义,它们不应该是公共的。否则,存在公开
    late
    变量的有效用例。请参阅他的描述性评论!
  • 请确保在所有构造函数、退出变量和新兴变量中初始化
    late
    变量。 在无法访问的代码场景中初始化
  • late
  • 变量时请务必小心。例子:
      late
    • 变量在
      if
      子句中初始化,但
      else
      中没有初始化,反之亦然。
      一些控制流短路/提前退出阻止执行到达
    • late
    • 变量初始化的行。
      
      
  • 如有错误/补充,请指出。

享受吧!

来源:

    eernstg 的看法
  • Hixie 的拍摄
  • lrhn 的看法
  • leafpetersen 截至 2021 年 10 月 22 日的最终判决
  • 有效飞镖
  • 自我分析如何用一些常识来处理这个问题。

8
投票

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. }



7
投票

我们有一个实例,如果小部件加载失败,则它会被释放,并且包含一个在加载时填充的后期控制器。由于控制器为空,处置失败,但这是控制器可以为空的唯一情况。我们将 dispose 包装在 try catch 中来处理这种情况。


7
投票
使用 nullable 而不是 Late:

File? file; File myFile; if (file == null) { file = File(); } myFile = file!;

请注意 
myFile = file!;

中的感叹号,这会将

File?
转换为
File
    


1
投票

我正在分享我的代码块,这种方法可以使用全局布尔变量轻松实现到项目中。 我的问题是当用户快速打开和关闭页面时,我从 dispose 方法中得到的异常


0
投票

如果需要检查后期变量是否已初始化,请避免使用它们

在这里阅读 ->
https://dart.dev/ effective-dart/usage#avoid-late-variables-if-you-need-to-check-whether-they-are-initialized


-1
投票

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"); } }

© www.soinside.com 2019 - 2024. All rights reserved.