[英]How does the initialization of classes in Scala work?
下面的代碼會拋出java.lang.NullPointerException
,因為過早地初始化了 trait。
trait DummyTrait {
def intSeq: Seq[Int]
require(intSeq.exists(_ > 2))
}
object Dummy extends DummyTrait {
val extraIntSeq: Seq[Int] = Seq(-2,-3)
override def intSeq = Seq(1,0,4) ++ extraIntSeq
}
Dummy.intSeq
但是,下面的簡單更改解決了這個問題,但我不明白為什么。
trait DummyTrait {
def intSeq: Seq[Int]
require(intSeq.exists(_ > 2))
}
object Dummy extends DummyTrait {
lazy val extraIntSeq: Seq[Int] = Seq(-2,-3) // using `def` also works
override def intSeq = Seq(1,0,4) ++ extraIntSeq
}
Dummy.intSeq
我發現this documentation about overriden val is NULL ,但它似乎不適用於上面的示例,因為修復不涉及在超類的接口中定義的變量。
另外,上面提出的解決方案是反模式嗎? 作為正在開發該特征的人,我應該如何強制執行抽象值的要求,而不會讓使用潛在NullPointerException
實現子 class 的用戶感到驚訝?
觀察:我正在使用 Scala 版本 2.13.0
在第一種情況下,在調用超級構造函數之后,在構造函數中初始化了extraIntSeq
,因此 NPE
object Dummy extends DummyTrait {
private[this] val extraIntSeq: Seq = _;
...
def <init>($outer: O): Dummy.type = {
Dummy.super.<init>();
Dummy.this.extraIntSeq = ... // note that it comes AFTER super
()
}
}
而在后者中,惰性 val 變成了方法。
到目前為止,您可以使用早期初始化程序
object Dummy extends {
val extraIntSeq: Seq[Int] = Seq(-2,-3)
override val intSeq = Seq(1,0,4) ++ extraIntSeq
} with DummyTrait
https://dotty.epfl.ch/docs/reference/dropped-features/early-initializers.html
https://contributors.scala-lang.org/t/proposal-to-remove-early-initializers-from-the-language/2144
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.