是否可以使用类方法初始化Dart中的最终属性?

是否可以使用类方法初始化Dart中的最终属性?,dart,Dart,假设我有一个类,其中包含在初始化期间传递的函数: 类调用者{ 最终_controller=StreamController(); 调用者(无效函数(int)回调){ _controller.stream.listen(回调); } 无效发送(int x){ _controller.sink.add(x) } } 是否可以使用另一个类方法初始化调用方,同时将其标记为最终 类容器{ 最终呼叫者(u呼叫者),; int _val=0; 无效_doSomething(int x){ _val+=x;

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

类调用者{
最终_controller=StreamController();
调用者(无效函数(int)回调){
_controller.stream.listen(回调);
}
无效发送(int x){
_controller.sink.add(x)
}
}
是否可以使用另一个类方法初始化调用方,同时将其标记为最终

类容器{
最终呼叫者(u呼叫者),;
int _val=0;
无效_doSomething(int x){
_val+=x;
_调用方。发送(_val);
}
容器():_caller=caller(_doSomething);
}
Dart抱怨
“只有静态成员才能在初始化器中访问。”
我知道在调用构造函数之前不能访问未初始化的参数,但默认情况下“方法”不是最终的吗?与其他属性不同,它不能动态修改

因此,除了在构造函数中标记
\u caller
非final并对其进行初始化之外,还有什么解决方法吗?

在初始化器中只能访问静态成员。是关于
\u doSomething
方法,您将其作为参数提供给
caller
构造函数。由于
\u doSomething
方法在构造步骤中不可用(因为该方法是尚未构造的对象的成员),因此您不能在此处使用它。

方法“只能在初始值设定项中访问静态成员。”
是关于
\u doSomething
方法的,该方法作为
调用方的参数提供给
构造函数。由于
\u doSomething
方法在构造步骤中不可用(因为该方法是尚未构造的对象的成员),因此您不能在此处使用它。

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

对于这种特殊情况,您可以提供一种在创建
调用者
后使用回调调用
listen
方法的方法。您可以在调用
listen
之前创建
调用者
。(如果不使用
listen
返回的
StreamSubription
,我建议使用
forEach
而不是
listen

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

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) { ... }
}
类调用者{
最终_controller=StreamController();
调用者(无效函数(int)回调){
_控制器forEach(回调);
}
类容器{
迟到的最后一个呼叫者=呼叫者(这个._doSomething);
容器(){
_呼叫者;
}
void_doSomething(int x){…}
}
这个迟来的
\u调用者
字段将在您第一次读取它时初始化。它仍然是最终的,您可以通过读取它来强制在构造函数中读取它。它有点黑客化,主要是因为要初始化的伪读取。

当前无法创建仅通过最终字段相互引用的两个对象,或将彼此传递给其他对象的构造函数的两个对象。在对该对象的任何引用可用之前,必须初始化最终字段,并且无法在另一个对象之前创建这两个对象

对于这种特殊情况,您可以提供一种方法,在创建
调用者
之后通过回调调用
listen
方法。您可以在调用
listen
之前创建
调用者
。(如果不使用
listen
返回的
StreamSubription
,我建议使用
forEach
而不是
listen

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

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) { ... }
}
类调用者{
最终_controller=StreamController();
调用者(无效函数(int)回调){
_控制器forEach(回调);
}
类容器{
迟到的最后一个呼叫者=呼叫者(这个._doSomething);
容器(){
_呼叫者;
}
void_doSomething(int x){…}
}

这个迟来的
\u调用者
字段将在您第一次读取它时初始化。它仍然是最终的,您可以通过读取它来强制在构造函数中读取它。这有点粗糙,主要是因为初始化时的伪读取。

我理解这一点。我正在寻求一种可能的解决方法,允许我通过
\u doS向
调用者
构造函数发送某个东西,并将
\u调用者
保留为
最终的
。为什么
\u调用者
是最终的很重要?没有那么“重要”,但是
\u调用者
容器
的生命周期内几乎没有理由更改,所以我认为这就是
final
关键字的用途。我理解这一点。我正在寻求一种可能的解决方法,允许我将
\u doSomething
传递给
调用者
构造函数并保留
\u调用者
作为
final
。为什么
\u调用者
是final很重要?没有那么“重要”,但是
\u调用者
容器
的生命周期内几乎没有理由更改,所以我认为这就是
final
关键字的用途。感谢您的详细解释,我非常感谢!您建议使用第二种方法是我已经实现的。它没有强制执行这一点“控制器应该只听一次”,这就是为什么我想知道是否还有其他的方法。很高兴听到关于未来的
late
关键字。顺便说一句,Dart是一种经过深思熟虑且令人愉快的语言