2010-09-17 73 views
2

我得到了下面的代碼段指在「編程的Scala」第6章的例子:爲什麼對於抽象特徵成員val初始化的細微變化,結果會有所不同?

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 = 10println("In c2b:"),結果將是:

In AbstractT2: 
AbstractT2: value = 10, inverse = 0.1 
In c2b: 
c2b.value = 10, inverse = 0.1 

看來這一次初始化成功,雖然它是從語言觀點是錯誤的。我不明白爲什麼。有人可以幫助嗎?非常感謝。

+0

嗯......對Scala 2.8.0.final進行了驗證,並在兩種情況下看到相同的結果:In AbstractT2: AbstractT2:value = 0,inverse = Infinity In c2b: c2b.value = 10, inverse = Infinity – 2010-09-17 06:27:32

+0

我可以確認Vasil的評論。和Scala 2.8.0.final一樣。你使用什麼版本? – 2010-09-17 06:46:53

+0

我用來獲得上述結果的版本是2.7.7.final。我剛剛對2.8.0進行了測試,兩種情況的結果都是正確的,正如你所說的。所以它似乎是2.7.7或2.7.x的錯誤? – Hongfei 2010-09-17 09:50:13

回答

3

高達2.7斯卡拉移動在父類的構造 前值初始化,直到它引用遇到this初始化。它會停止。 很多很早以前,這種行爲對於獲得一些構圖模式起作用是必需的。後來,我們引入了早期的定義,以更強大的方式獲得相同的模式。但是由於行爲很難改變,我們直到2.8才真正做到這一點。

5

初始化語義從2.7更改爲2.8。這是2008年的承諾,早在2008年。「硬帽子!」

https://lampsvn.epfl.ch/trac/scala/changeset/16745

+0

嗨,你的意思是2.7中的當前行爲也是正確的嗎?謝謝。 – Hongfei 2010-09-17 10:03:46

+0

我的意思是你正在演示的行爲是2.7中的預期行爲。 「正確」是一個更加雄心勃勃的說法,我既不能肯定也不否認,但除非你想開始維護2.7分支,否則這個問題就沒有意義了。 – extempore 2010-09-17 23:55:39

相關問題