Dart构造函数初始化顺序

问题描述 投票:2回答:2
class Base {
  num b;
  Base() {
    print("in Base");
  }

  Base.initB(b) {
    b = b;
    print("in Base.initB");
  }
}

class Point extends Base {
  num x;
  num y;
  final num f;

  Point(this.x, int y, smth, b): f=smth, super.initB(b) {
    print(this.x);
    this.y = y;
  }
}

main() {
  var a = new Point(1, 2, 3, 4); 
  // output:
  // in Base initB
  // 1
}

我正在学习Dart,但发现文档模糊不清。我想知道实例变量的初始化顺序。有两个问题:

  1. 根据我的理解,初始化顺序是x, f -> b -> y,是否正确?
  2. xf,这是第一个?
dart
2个回答
1
投票

我不认为xf之间有一个订单,如果是,那就无所谓了。你无法从任何地方访问xf,直到suber.initB(b)完成并且Point的构造函数体开始被执行。

除此之外,您获得的顺序是正确的。


3
投票

我可以理解文档似乎模糊不清。我相信对象初始化完全破坏了,它在"to-fix" list上。

实际上,初始化列表的评估顺序是从左到右。你可以通过在初始化表达式中有副作用来看到它。

对超级构造函数的调用发生在最后(在VM中),或者在超级调用发生的位置(在Dart2JS中)。因此,建议您始终将超级呼叫置于最后,并且可能在更高版本的Dart中需要。把它放在早期没有任何好处。

在执行了所有初始化程序列表并且已经处理了所有初始化形式(如上面的this.x)之后,该对象被认为是初始化的,然后构造函数体以超类的第一顺序执行,并以this的形式访问新对象。

设置实际对象字段时未定义。在初始化所有字段后,您才会看到该对象。在评估初始化列表时,将所有值放在堆栈上,然后在进入第一个构造函数体之前分配对象,这是一个非常有效的实现策略。

这是显示评估顺序的an example

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