使用来自 Scala case 对象的超类的 require 子句
Using a superclass' require clause from a Scala case object
我有下面的 Scala 代码,我想在其中使用来自 case 对象的超类的 require
子句,其中 require
中使用的参数被覆盖:
sealed abstract class C(val i: Int) {
protected val min: Int = 1
protected val max: Int = 5
require(i >= min && i <= max,
s"$i should be between $min and $max, inclusive")
}
case object O extends C(3) {
override protected val min: Int = 3
override protected val max: Int = 5
}
println(O)
但是,打印 O
给了我 java.lang.IllegalArgumentException: requirement failed: 3 should be between 0 and 0, inclusive
异常。
仅覆盖其中一个参数:
case object O extends C(3) {
override protected val max: Int = 5
}
导致异常 java.lang.IllegalArgumentException: requirement failed: 3 should be between 1 and 0, inclusive
。
对我来说,这表明超类 require
在 case 对象中的参数覆盖发生之前被调用,但不知何故编译器 "knows" 会发生覆盖,并且它需要参数数据类型的默认值,在本例中为零。
为什么会这样,当对象中的参数被覆盖时,如何使用超类的参数化 require
子句?
您对执行顺序和初始化的假设是正确的。
要解决此问题,您有几种不同的选择。一种是让每个 val
都被覆盖为 lazy val
,像这样:
sealed abstract class C(val i: Int) {
protected lazy val min: Int = 1
protected lazy val max: Int = 5
require(i >= min && i <= max,
s"$i should be between $min and $max, inclusive")
}
case object O extends C(3) {
override protected lazy val min: Int = 3
override protected lazy val max: Int = 5
}
另一种方法是在覆盖时使用 "early definition" 语法。 abstract class
代码未更改,但 object
看起来像这样。
case object O extends {
override protected val min: Int = 3
override protected val max: Int = 5
} with C(3)
第三种选择是使用 "constant value definitions",但这往往更麻烦且不太方便。
有关所有三个选项的详细信息,请访问 this FAQ。
我有下面的 Scala 代码,我想在其中使用来自 case 对象的超类的 require
子句,其中 require
中使用的参数被覆盖:
sealed abstract class C(val i: Int) {
protected val min: Int = 1
protected val max: Int = 5
require(i >= min && i <= max,
s"$i should be between $min and $max, inclusive")
}
case object O extends C(3) {
override protected val min: Int = 3
override protected val max: Int = 5
}
println(O)
但是,打印 O
给了我 java.lang.IllegalArgumentException: requirement failed: 3 should be between 0 and 0, inclusive
异常。
仅覆盖其中一个参数:
case object O extends C(3) {
override protected val max: Int = 5
}
导致异常 java.lang.IllegalArgumentException: requirement failed: 3 should be between 1 and 0, inclusive
。
对我来说,这表明超类 require
在 case 对象中的参数覆盖发生之前被调用,但不知何故编译器 "knows" 会发生覆盖,并且它需要参数数据类型的默认值,在本例中为零。
为什么会这样,当对象中的参数被覆盖时,如何使用超类的参数化 require
子句?
您对执行顺序和初始化的假设是正确的。
要解决此问题,您有几种不同的选择。一种是让每个 val
都被覆盖为 lazy val
,像这样:
sealed abstract class C(val i: Int) {
protected lazy val min: Int = 1
protected lazy val max: Int = 5
require(i >= min && i <= max,
s"$i should be between $min and $max, inclusive")
}
case object O extends C(3) {
override protected lazy val min: Int = 3
override protected lazy val max: Int = 5
}
另一种方法是在覆盖时使用 "early definition" 语法。 abstract class
代码未更改,但 object
看起来像这样。
case object O extends {
override protected val min: Int = 3
override protected val max: Int = 5
} with C(3)
第三种选择是使用 "constant value definitions",但这往往更麻烦且不太方便。
有关所有三个选项的详细信息,请访问 this FAQ。