我想我明白斯卡拉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的机器,所以我不知道。我会尽力检查。 –