我想我明白斯卡拉2.10的新的「值類」功能,通過與Haskell的newtype
比較:用戶定義的值類在Java中看起來如何?
trait BoundedValue[+This] extends Any { this: This =>
def upperBound: This
def lowerBound: This
}
class Probability @throws(classOf[IllegalArgumentException]) (v: Double) extends AnyVal with BoundedValue[Probability] {
val value: Double = if ((v >= 0.0) && (v <= 1.0)) v else throw new IllegalArgumentException((v.toString) + "is not within the range [0.0, 1.0]")
override val upperBound: Probability = new Probability(0.0)
override val lowerBound: Probability = new Probability(1.0)
// Implement probability arithmetic here;
// will be represented by Double at runtime.
}
這個問題我有是,如何值類出現的Java代碼,使用Scala的包在哪裏宣佈?值類是從Java端作爲引用類出現的,還是被完全擦除(並因此顯示爲它所包裝的類型)?換句話說,當Java在源代碼級別上涉及時,類型安全是否是值類?
EDIT
上面的代碼不會編譯,根據SIP-15文件(丹尼爾的回答聯的),因爲值類不允許有任何初始化邏輯,因爲要麼v
必須顯式爲val或必須有一個unbox
方法和相應的box
方法對其伴侶對象,並且因爲值類必須只有一個字段。正確的代碼是:
trait BoundedValue[This <: BoundedValue[This]] extends Any { this: This =>
def upperBound: This
def lowerBound: This
}
class Probability private[Probability] (value: Double) extends AnyVal with BoundedValue[Probability] {
@inline override def upperBound: Probability = new Probability(0.0)
@inline override def lowerBound: Probability = new Probability(1.0)
@inline def unbox: Double = value
// Implement probability arithmetic here;
// will be represented by Double at runtime (mostly).
}
object Probability {
@throws(classOf[IllegalArgumentException])
def box(v: Double): Probability = if ((v >= 0.0) && (v <= 1.0)) new Probability(v) else throw new IllegalArgumentException((v.toString) + "is not within the range [0.0, 1.0]")
}
但是,問題本身仍然有效。
在你的測試程序中,你是否能夠將包裝值從Java的有效邊界之外推送出去? –
@DavidHarkness我現在無法使用裝有2.10.0-M4的機器,所以我不知道。我會盡力檢查。 –