Scala 嵌套对象和成员变量的构造顺序
我在REPL中创建这个对象。然后在下图中测试其设置顺序。结果令人困惑Scala 嵌套对象和成员变量的构造顺序,scala,Scala,我在REPL中创建这个对象。然后在下图中测试其设置顺序。结果令人困惑 object T { val default = A var options = List[P]() println(options) sealed trait P object A extends P { override def toString = "A" println(T.options) println("A") } object B extends P {
object T {
val default = A
var options = List[P]()
println(options)
sealed trait P
object A extends P {
override def toString = "A"
println(T.options)
println("A")
}
object B extends P {
override def toString = "B"
println(T.options)
println("A")
}
object C extends P {
override def toString = "C"
println(T.options)
println("A")
}
}
T
,似乎只构造了内部对象A
。
为什么对象B
和对象C
不打印任何内容
因为它们没有初始化,所以只声明它们。打印出A
的原因是:
val default = A
这会导致A
初始化。因此,初始化的顺序是:
T
sdefault
变量导致A
初始化A
初始化并打印null
T
现在继续初始化,并将值设置为options
null
还请注意,第一次运行时println(T.options)
返回“null”。是
这是因为首先设置内部对象,然后设置外部对象
其他成员是否已设置
这是因为println(T.options)
发生在A
s构造函数中,它在T
s构造函数中的options
初始化之前
键入T.A
时,由于对象已设置,因此不会打印任何内容
这很有道理,A
没有任何需要初始化的附加内容
在键入T.B
时,它设置B
对象并打印T.options
正确,即List()
而不是null
没错,因为一旦调用了
T.B
,您就已经通过T
s构造函数初始化了列表。感谢您的详细解释。val default=A
是这里的魔鬼(@Samar,不客气。是的,这就是导致一连串调用的原因。