【发布时间】:2020-09-09 20:23:21
【问题描述】:
下面的代码抛出一个java.lang.NullPointerException,因为这个特征被过早地初始化了。
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 being NULL,但它似乎不适用于上面的示例,因为修复不涉及在超类的接口中定义的变量。
另外,上面提出的解决方案是反模式吗?作为开发 trait 的人,我应该如何强制要求抽象值,而不会让实现具有潜在 NullPointerException 的子类的用户感到惊讶?
Obs.:我使用的是 Scala 版本 2.13.0
【问题讨论】:
-
我宁愿使用精炼类型或智能构造函数,但无论如何这个问题很有趣。
标签: scala initialization traits initializer anti-patterns