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