Scala mixin将重写的变量设置为null

时间:2014-09-10 06:21:37

标签: scala mixins

我有以下情况:

class A {
  val text = "Test"
  //some initialization things using text. here represented by println
  println(text)
}

现在我想为该类编写单元测试,因此为此目的更改text的值。

trait Test extends A {
  override val text = "Hello"
}

class B extends A with Test 

现在的问题是,如果我创建B的实例,则文本的值按预期设置为"Hello",但A中的所有初始化步骤都会得到null的值1}} text

See this fiddle for demo

我的问题是为什么变量null为原始class A中的语句?我觉得拥有旧值似乎比没有突然没有价值更合乎逻辑。

2 个答案:

答案 0 :(得分:4)

编写val text = ...时,编译器会生成一个私有final字段(让我们称之为_text)和一种访问它的方法。 AB都会发生这种情况。 B的构造函数首先调用A的构造函数,但它使用的text方法是B;所以它访问B._text,它尚未初始化!

作为@ DennisTraub答案中def的替代方法,您还可以使用lazy val来避免重新计算答案(def在这种情况下更好)。在我看来,你通常不应该覆盖val以避免这样的问题。

答案 1 :(得分:2)

不幸的是我不知道它为什么会这样,但是我使用def代替val解决了手头的问题:

class A {
  def text = "Test"
  println(text)
}

trait Mix extends A {
  override def text = "Hello"
}