Credo di capire la nuova funzione di "classe di valore" di Scala 2.10, dal confronto con newtype
di Haskell:Che aspetto hanno le classi di valore definite dall'utente da 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.
}
La domanda che ho è, come fa una classe di valori sembrano codice Java che utilizza il pacchetto Scala in cui è dichiarato? La classe value appare come una classe di riferimento dal lato Java, oppure viene cancellata completamente (e quindi appare come il tipo che esegue il wrapping)? In altre parole, quanto sono sicuri i tipi sono classi di valore quando Java è coinvolto nel livello sorgente?
EDIT
Il codice di cui sopra non viene compilato, secondo il documento SIP-15 (collegato nella risposta di Daniel), perché classi di valore non è consentito avere qualsiasi logica di inizializzazione, perché o v
deve essere esplicitamente val o Probability
deve avere un metodo unbox
e un corrispondente metodo box
sul suo oggetto companion e poiché le classi valore devono avere esattamente un campo. Il codice corretto è:
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]")
}
La domanda stessa è ancora valido come è, tuttavia.
Nel programma di test, è stato possibile trasferire il valore spostato all'esterno dei limiti validi da Java? –
@DavidHarkness In questo momento non ho accesso ad una macchina con 2.10.0-M4, quindi non lo so. Controllerò quando posso. –