我在“Programming Scala”的第6章中引用了以下代码片段:
object HelloWorld {
def main(args: Array[String]) {
trait AbstractT2 {
println("In AbstractT2:")
val value: Int
val inverse = 1.0 / value // ???
println("AbstractT2: value = " + value + ", inverse = " + inverse)
}
val c2b = new AbstractT2 {
println("In c2b:") //---->line 1
val value = 10 //---->line 2
}
println("c2b.value = " + c2b.value + ", inverse = " + c2b.inverse)
}
}
上述代码的结果是:
In AbstractT2:
AbstractT2: value = 0, inverse = Infinity
In c2b:
c2b.value = 10, inverse = Infinity
由于匿名类初始化是在特征初始化之后,因此结果是可以理解的。但是,如果我在上面的例子中交换第1行和第2行,那么val value = 10
在println("In c2b:")
之前,结果将是:
In AbstractT2:
AbstractT2: value = 10, inverse = 0.1
In c2b:
c2b.value = 10, inverse = 0.1
这次初始化成功似乎虽然从语言的角度来看是错误的。我不明白为什么。有人可以帮忙吗?非常感谢。
答案 0 :(得分:5)
初始化语义从2.7变为2.8。这是2008年的提交。“HARD HATS ON!”
答案 1 :(得分:3)
最多2.7个Scala在超类构造函数前移动了值初始化
直到遇到引用this
的初始化。它会停止。
很久以前,这种行为对于使一些组合模式起作用是必要的。后来,我们引入了早期定义,以更健壮的方式使相同的模式工作。
但由于这种行为很难改变,所以我们直到2.8才真正去做。