Chyba rozumiem nowej „klasy wartość” cechę Scala 2.10, w porównaniu z Haskell za newtype
:Jak wyglądają zdefiniowane przez użytkownika klasy wartości z 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.
}
Mam pytanie jest, w jaki sposób klasa wartość wydaje się kod Java, który używa pakietu Scala w którym jest zadeklarowany? Czy klasa wartości pojawia się jako klasa odniesienia po stronie Java, czy też jest całkowicie wymazana (i dlatego pojawia się jako typ, który jest zawijany)? Innymi słowy, w jaki sposób bezpieczne dla typów są klasy wartości, gdy Java jest zaangażowana na poziomie źródłowym?
EDIT
Powyższy kod nie będzie kompilować, zgodnie z SIP-15 dokumentu (połączonego w odpowiedzi Daniela), ponieważ klasy wartości nie mogą mieć żadnej logiki inicjalizacji, ponieważ albo v
musi być jawnie wartością val lub Probability
musi mieć metodę unbox
i odpowiednią metodę box
na swoim obiekcie towarzyszącym, a ponieważ klasy wartości muszą mieć dokładnie jedno pole. Prawidłowy kod to:
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]")
}
Samo pytanie jest jednak nadal aktualne.
W swoim programie testowym, czy byłeś w stanie wypchnąć zawiniętą wartość poza prawidłowe granice z Java? –
@DavidHarkness Nie mam teraz dostępu do komputera z 2.10.0-M4, więc nie wiem. Sprawdzę, kiedy będę mógł. –