¿Cómo se ven las clases de valor definidas por el usuario desde Java?

Creo que entiendo la nueva característica de "clase de valor" de Scala 2.10, en comparación con Haskell 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.

}

La pregunta que tengo es, ¿cómo aparece una clase de valor en el código Java que usa el paquete Scala en el que se declara? ¿Aparece la clase de valor como una clase de referencia desde el lado de Java, o se borra por completo (y, por lo tanto, aparece como el tipo que envuelve)? En otras palabras, ¿qué tan seguras son las clases de valor cuando Java está involucrado en el nivel de fuente?


EDITAR

El código anterior no se compilará, de acuerdo con el documento SIP-15 (vinculado en la respuesta de Daniel), porque las clases de valor no pueden tener ninguna lógica de inicialización, porque tampoco v debe ser explícitamente un valor o Probability debe tener un unbox método y un correspondiente box método en su objeto complementario, y porque las clases de valor deben tener exactamente un campo. El código correcto es:

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]")

}

Sin embargo, la pregunta en sí sigue siendo válida tal como está.

preguntado el 30 de junio de 12 a las 19:06

En su programa de prueba, ¿pudo empujar el valor envuelto fuera de los límites válidos de Java? -

@DavidHarkness No tengo acceso a una máquina con 2.10.0-M4 en este momento, así que no lo sé. Lo comprobaré cuando pueda. -

1 Respuestas

Las clases de valor se compilan como clases normales y pueden aparecer como referencias.

La magia en ellos es que, cuando la clase de valor no escapa del alcance, todos sus rastros se borran del código, insertando efectivamente todo el código. Y, por supuesto, dando seguridad de tipo adicional.

Vea también SORBO-15, que explica la mecánica.

Respondido 01 Jul 12, 04:07

¡Gracias! Pensé que había leído el SIP, pero supongo que no. - Llama de Ptharien

Una pregunta igualmente interesante como "¿cómo se codifican los tipos de valor de Scala en una plataforma que no tiene tipos de valor en sí misma (por ejemplo, JVM)" es "¿cómo se codifican los tipos de valor de Scala en una plataforma que tener tipos de valores en sí mismos (por ejemplo, CLI)". Por ejemplo, ¿los tipos de valores de Scala se pueden compilar en estructuras en la CLI? ¿Se garantiza que siempre ser compilado a estructuras? - Jörg W. Mittag

Su pregunta es muy interesante, pero me di cuenta de que no solo las estructuras CLI no son compatibles (no se mencionaron en el SIP, la última vez que lo leí), sino que probablemente también sean inútiles. Las clases de valor solo pueden tener un solo campo, como los nuevos tipos de Haskell, por lo tanto, creo que usar estructuras y no primitivos no ayudaría. Las estructuras tienen muchas ventajas para el uso de la memoria, pero para usarlas, se debe proporcionar un mecanismo separado, es decir, una anotación que solicite este comportamiento que se puede ignorar. El problema semántico es que las estructuras probablemente deberían heredar de AnyVal solo en la CLI, no en la JVM. - Blaisorblade

Es incorrecto, por lo que he entendido, que una clase de valor que escapa del alcance se encuadre (es decir, que el valor estaría envuelto en un objeto, en lugar de en línea). De hecho, el valor está entre líneas "casi siempre" :-) Ver respuestas a mi pregunta En estos casos, la clase de valor de Scala estará "encuadrada", ¿verdad? - kajmagnus

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.