我尝试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初始化应该按照需要工作.