开发者

Why is the result different for a tiny change regarding abstract trait member val initialization?

I got the following code snippet referring an example in Chapter 6 of "Programming Scala":

object HelloWorld {
  def main(args: Array[String]) {
    trait AbstractT2 {
      println("In AbstractT开发者_如何学Go2:")
      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)
  }
}

The result of the above code is:

In AbstractT2:
AbstractT2: value = 0, inverse = Infinity
In c2b:
c2b.value = 10, inverse = Infinity

Since the anonymous class initialization is after the trait initialization, the result is understandable. But if I exchange line 1 and line 2 in the above example, so that val value = 10 precedes println("In c2b:"), the result will be:

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

It seems this time the initialization is successful although it's wrong from language point of view. I can't understand why. Can anybody help on this? Thanks a lot.


Initialization semantics changed from 2.7 to 2.8. Here's the commit, way back in 2008. "HARD HATS ON!"

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


Up to 2.7 Scala moved value initializations in front of the superclass constructor until an initialization which references this was encountered. There it would stop. Much, much earlier, this behavior was necessary to get some composition patterns working. Later, we introduced early definitions to get the same patterns working in a more robust way. But since the behavior was difficult to change it took us until 2.8 to actually do it.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜