用户定义的值类在Java中是什么样子的?
通过与Haskell的用户定义的值类在Java中是什么样子的?,java,scala,interop,scala-java-interop,newtype,Java,Scala,Interop,Scala Java Interop,Newtype,通过与Haskell的newtype,我想我理解了Scala 2.10的新“值类”特性: trait BoundedValue[+This] extends Any { this: This => def upperBound: This def lowerBound: This } class Probability @throws(classOf[IllegalArgumentException]) (v: Double) extends AnyVal with Bou
newtype
,我想我理解了Scala 2.10的新“值类”特性:
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.
}
然而,这个问题本身仍然是有效的。值类作为普通类编译,很可能作为引用出现 它们的神奇之处在于,当value类没有脱离作用域时,它的所有痕迹都会从代码中删除,从而有效地内联所有代码。当然,还提供了额外的类型安全性
另请参见,这解释了机制。在您的测试程序中,您是否能够将包装的值推到Java的有效边界之外?@DavidHarkness我现在无法访问带有2.10.0-M4的机器,所以我不知道。我可以的时候再查。谢谢!我以为我读过SIP,但我想我没有读过。一个同样有趣的问题是“在一个本身没有值类型的平台(如JVM)上如何对Scala值类型进行编码”是“在一个本身有值类型的平台(如CLI)上如何对Scala值类型进行编码”。例如,是否可以通过在CLI上编译为structs来缩放值类型?您的问题很有意思,但我意识到,不仅CLI结构不受支持(上次阅读时,SIP中没有提到它们),而且它们可能也没用。值类只能有一个字段,就像Haskell的newtypes一样,因此我认为使用结构而不是原语是没有帮助的。结构在内存使用方面有很多优势,但要使用它们,应该提供一个单独的机制,即一个请求这种行为的注释,可以忽略它。语义问题是结构可能只在CLI上继承AnyVal,而不是在JVM上。据我所知,逃逸范围的值类将被装箱是不正确的(我的意思是,值将被包装在对象中,而不是内联)。事实上,该值是内联的“几乎总是”:-)请参阅我问题的答案
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]")
}