scala> trait A { val a = { println("i'm invoked"); "1" } }
defined trait A
scala> class B extends A { override val a = { println("i'm invoked B"); "2" } }
defined class B
scala> (new B).a
i'm invoked
i'm invoked B
res0: String = 2
如何避免对val a
中的trait A
进行评估?我尝试使用lazy val
可以正常工作,但是想知道是否还有其他方法可以做到。谢谢。
答案 0 :(得分:4)
如本Scala doc中所述:
严格val的初始化按以下顺序进行:
- 超类在子类之前被完全初始化。
- 否则,按照声明顺序。
子句“之前已完全初始化”解释了为何尽管严格val
在子类中被覆盖,但仍对其进行求值。
除了lazy val
以外,另一种方法是将val
替换为特征中的def
:
trait A { def a = { println("i'm invoked"); "1" } }
class B extends A { override def a = { println("i'm invoked B"); "2" } }
(new B).a
// i'm invoked B
// res1: String = 2