Sat Feb 27 12:16:23 JST 2016

参考文献

Scala, 継承の評価順序

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

.strBA を継承した時点で評価されて class Cstr1 より先である.

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 の継承の際にそれを使って評価される.