如何在subtrait中初始化trait的vals?

Ric*_*ard 5 scala traits

我尝试val在特征中使用抽象来初始化另一个值.我有一个NullPointerException.我把这个行为简化为一个最小的测试用例:

trait MessagePrinter {
  val message: String
  println(message)
}

class HelloPrinter extends MessagePrinter {
  val message = "Hello World"
}

val obj = new HelloPrinter()
println(obj.message)
Run Code Online (Sandbox Code Playgroud)

这个小程序产生以下结果:

null
Hello World
Run Code Online (Sandbox Code Playgroud)

我的印象是val可能永远不会改变.这是预期的行为还是编译器错误?如何解决此问题并Hello World在初始化期间进行打印?

Ben*_*ich 11

根据Scala规范的第5.1节,首先初始化超类.即使vals通常无法重新实例化,它们也会在构造期间以默认初始值开始.您可以使用def,它具有不同的语义:

trait MessagePrinter {
   def message: String
   println(message)
}

class HelloPrinter extends MessagePrinter {
   def message = "Hello World"
}
Run Code Online (Sandbox Code Playgroud)

或者你可以考虑改变这样的事情:

class HelloPrinter extends { val message = "Hello World" } with MessagePrinter 
Run Code Online (Sandbox Code Playgroud)

在这种情况下,按顺序评估超类,以便MessagePrinter初始化应该按照需要工作.