Usually the "memeber" in trait is defined as def variable:Type
, then other memebers which depend on variable
uses lazy val
to prevent variable
being null when getting initialized.
However if it is a piece of logic, e.g. a function call depends on variable
will still throw null exception. Like the code below:
trait A {
def variable:Seq[String]
if (variable.size > 3) // check
println("too many strings")
}
case class B(vs:String*) extends A {
override val variable: Seq[String] = vs
//override def hi(): Unit = ???
}
val b = B("x", "y", "z")
println(b)
This will throw error "A.variable() is null".
Strangely, if I wrote variable as given constructor parameter, the error is gone.
case class B(override val variable:String*) extends A {
//override def hi(): Unit = ???
}
How I can delay the "check" and why the second case doesn't throw exception?
CodePudding user response:
That's a use case for early initializers
case class B(vs: String*) extends {
override val variable: Seq[String] = vs
} with A {
//override def hi(): Unit = ???
}
In Scala, what is an "early initializer"?
https://docs.scala-lang.org/scala3/reference/dropped-features/early-initializers.html