如果特质的值在课堂上被覆盖,为什么要对其进行评估?

时间:2018-12-12 01:53:30

标签: scala

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可以正常工作,但是想知道是否还有其他方法可以做到。谢谢。

1 个答案:

答案 0 :(得分:4)

如本Scala doc中所述:

  

严格val的初始化按以下顺序进行:

     
      
  1. 超类在子类之前被完全初始化。
  2.   
  3. 否则,按照声明顺序。
  4.   

子句“之前已完全初始化”解释了为何尽管严格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