scala> :paste
// Entering paste mode (ctrl-D to finish)
trait A { val str1: String }
trait B extends A { val str = str1 + ", world" }
class C extends B { val str1 = "Hello" }
// Exiting paste mode, now interpreting.
defined trait A
defined trait B
defined class C
scala> (new C).str
res24: java.lang.String = null, world
.str
は B
が A
を継承した時点で評価されて class C
の str1
より先である.
scala> :paste
// Entering paste mode (ctrl-D to finish)
trait A { val str1: String }
trait B extends A { lazy val str = str1 + ", world" }
class C extends B { val str1 = "Hello" }
// Exiting paste mode, now interpreting.
defined trait A
defined trait B
defined class C
scala> (new C).str
res25: java.lang.String = Hello, world
lazy val
による遅延評価はこれを解決する.
scala> :paste
// Entering paste mode (ctrl-D to finish)
trait A { val str1: String }
trait B extends A { lazy val str = str1 + ", world" }
class C extends { val str1 = "Hello" } with B
// Exiting paste mode, now interpreting.
defined trait A
defined trait B
defined class C
scala> (new C).str
res26: java.lang.String = Hello, world
C
を、まず無名のクラス?フィールド?で継承させてから B
を継承させたような形で、クラス定義する. 無名のフィールドの部分を事前定義というらしく、B
の継承の際にそれを使って評価される.