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,但发现文档模糊不清。我想知道实例变量的初始化顺序。有两个问题:
x, f -> b -> y
,是否正确?x
和f
,这是第一个?答案 0 :(得分:3)
我可以理解文档似乎模糊不清。我认为对象初始化完全破坏了它,而且它在"to-fix" list上。
实际上,初始化列表的评估顺序是从左到右。你可以通过在初始化表达式中有副作用来看到它。
对超级构造函数的调用发生在最后(在VM中),或者在超级调用发生的位置(在Dart2JS中)。因此,建议您始终将超级呼叫置于最后,并且在更高版本的Dart中可能需要这样做。把它放在早期没有任何好处。
在执行了所有初始化程序列表并且已经处理了所有初始化形式(如上面的this.x
)之后,该对象被认为是初始化的,然后构造函数体以超类的第一顺序执行,并具有访问权限新对象为this
。
设置实际对象字段时未定义。在初始化所有字段后,您才会看到该对象。在评估初始化列表时,将所有值放在堆栈上,然后在进入第一个构造函数体之前分配对象,这是一个非常有效的实现策略。
以下是显示评估顺序的an example。
答案 1 :(得分:1)
我认为x
和f
之间没有定义订单,如果是,则无关紧要。在完成x
并且f
的构造函数体开始执行之后,您无法从任何地方访问suber.initB(b)
或Point
。
除了您导出的顺序是正确的。