通过与 Haskell 的比较,我想我了解 Scala 2.10 的新“价值类”功能newtype
:
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.
}
我的问题是,值类如何出现在使用声明它的 Scala 包的 Java 代码中?值类是作为 Java 端的引用类出现的,还是被完全删除(因此作为它包装的类型出现)?换句话说,当 Java 涉及到源代码级别时,值类的类型安全性如何?
编辑
根据 SIP-15 文档(在 Daniel 的回答中链接),上面的代码不会编译,因为值类不允许有任何初始化逻辑,因为要么v
必须是明确的 val,要么Probability
必须有一个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]")
}
然而,问题本身仍然有效。