私はHaskellのnewtype
と比較して、Scalaの2.10の新しい「値クラス」機能を理解すると思う:ユーザー定義の値クラスは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.
}
私が持っている問題は、値クラスはScalaのパッケージを使用するJavaコードに表示されないか、ありますそれは宣言されていますか?値クラスは、Java側からの参照クラスとして表示されるか、完全に消去される(したがって、ラップする型として表示されます)か?言い換えれば、Javaがソースレベルに関与しているときの型セーフはどのように値クラスですか?
値クラスは、任意の初期化ロジックを持つことが許されないため、上記のコードは、(ダニエルの答えにリンク)SIP-15文書によれば、コンパイルされません
EDIT、なぜならv
は明示的にvalでなければならず、はunbox
メソッドとそれに対応するbox
メソッドを持つ必要があります。また、値クラスには正確に1つのフィールドが必要です。正しいコードは次のとおりです。
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のマシンにアクセスできないので、わかりません。私はできる時を確認します。 –