首页 > 解决方案 > 是否可以使用类方法来初始化 Dart 中的最终属性?

问题描述

假设我有一个类,其中包含在其初始化期间传递的函数:

class Caller {
  final _controller = StreamController<int>();

  Caller(void Function(int) callback) {
      _controller.stream.listen(callback);
  }

  void send(int x) {
    _controller.sink.add(x)
  }
}

是否可以用另一个类方法初始化 aCaller同时也将其标记为final

class Container {
  final Caller _caller;
  int _val = 0;

  void _doSomething(int x) {
    _val += x;
    _caller.send(_val);
  }

  Container() : _caller = Caller(_doSomething);
}

Dart 抱怨说"Only static members can be accessed in initializers."我知道在调用构造函数之前你不能访问未初始化的参数,但是默认情况下“方法”实际上不是最终的吗?与其他属性不同,它不能动态修改。

那么,除了标记_caller非最终并在构造函数中对其进行初始化之外,还有其他解决方法吗?

标签: dart

解决方案


不。

您目前不能创建两个对象,它们仅通过最终字段相互引用,或者相互传递给其他对象的构造函数。在对对象的任何引用变为可用之前,必须初始化最终字段,并且无法在另一个对象之前创建两个对象。

对于这种特殊情况,您可以提供listen一种创建Caller. 您可以Caller在调用之前创建listen。(我建议在您不使用return by时使用forEach而不是)。listenStreamSubriptionlisten

在该语言的未来版本(以及不可为空的类型)中,我们打算引入后期初始化字段。然后就可以写了:

class Caller {
  final _controller = StreamController<int>();
  Caller(void Function(int) callback) {
    _controller.forEach(callback);
  }
}
class Container {
  late final _caller = Caller(this._doSomething);
  Container() {
    _caller;
  }
  void _doSomething(int x) { ... }
}

这个迟到_caller的字段将在您第一次阅读时被初始化。它仍然是最终的,您可以通过读取它来强制在构造函数中读取它。这有点骇人听闻,主要是因为虚假的读取初始化。


推荐阅读