Scala 如何初始化trait';什么是潜台词?
我尝试在trait中使用抽象的Scala 如何初始化trait';什么是潜台词?,scala,traits,Scala,Traits,我尝试在trait中使用抽象的val来初始化另一个值。我得到了一个NullPointerException。我将行为归结为一个最小的测试用例: trait MessagePrinter { val message: String println(message) } class HelloPrinter extends MessagePrinter { val message = "Hello World" } val obj = new HelloPrinter() print
val
来初始化另一个值。我得到了一个NullPointerException
。我将行为归结为一个最小的测试用例:
trait MessagePrinter {
val message: String
println(message)
}
class HelloPrinter extends MessagePrinter {
val message = "Hello World"
}
val obj = new HelloPrinter()
println(obj.message)
这个小程序产生以下结果:
null
Hello World
我的印象是,val可能永远不会改变。这是预期的行为还是编译器错误?如何解决此问题并在初始化过程中打印
Hello World
?在这两种情况下都应使用def
描述这种行为的来源之一是“拼图4:
以下规则控制初始化和重写行为
VAL的数量:
VAL
,但它们在构造过程中确实以默认初始值开始。您可以使用具有不同语义的def
:
trait MessagePrinter {
def message: String
println(message)
}
class HelloPrinter extends MessagePrinter {
def message = "Hello World"
}
或者你可以考虑像这样:
class HelloPrinter extends { val message = "Hello World" } with MessagePrinter
在这种情况下,将按顺序计算超类,以便
MessagePrinter
初始化应按需要工作。可能的解决方法:lazy val message
或def message
。不推荐使用的delayedInit
()也有类似的用途。这是一个JVM兼容性工件:遗憾的是,懒惰的VAL不能是抽象的。