Dart - 只允许设置类属性一次

问题描述

我想要一个只能设置一次的属性,然后忽略进一步设置它的尝试,因此没有人会意外设置或重置该值。

我知道 late 可以“有点”这样做,但是在使用 late 时,编译器和 IDE 都没有告诉我在调用 doOther() 之后调用 doOnce()会导致异常。

class Foo {
  bool? _bar;
  
  void doOnce() {
    if (_bar == null) {
      _bar = true;
      print('done this once');
    }
  }
  
  void doOther() {
    _bar = false; // this should not be possible when doOnce() is done
    print('done other');
  }
}

void main() {
  Foo foo = Foo();
  foo.doOnce();
}

解决方法

尽可能使用 late final

class Foo {
  late final int a;
  
  Foo();
  
  void doThing() {
    a = 5;
  }
  
  void doAnotherThing() {
    a = 3;
  }
}

...

void main() {
  final foo = Foo();

  // Uncaught Error: LateInitializationError: Field 'a' has not been initialized.
  // print(foo.a);

  foo.doThing();

  // Prints: 5
  print(foo.a);

  // Uncaught Error: LateInitializationError: Field 'a' has already been initialized.
  // foo.doAnotherThing();
}

这为您提供了您正在寻找的运行时行为,但没有解决方案可以为您提供静态编译时检查以分配给 late(或 late-ish)变量两次。这是因为为了知道您的程序正在尝试这样做,编译器必须检查程序中可能分配给 late 变量的每个路径,这可能需要很长时间。

简而言之,您将不得不练习自己的尽职调查,而不是依靠编译器或静态分析器来通知您错误。