scala casting playframework type-conversion options

Opción “Convertir”[x] a x en Scala



casting playframework (6)

Estoy trabajando con play para scala (2.1) y necesito convertir un valor de "Opción [Largo]" a "Largo".

Sé hacer lo contrario, quiero decir:

def toOption[Long](value: Long): Option[Long] = if (value == null) None else Some(value)

Pero en mi caso, tengo que pasar un valor de "Opción [Largo]" como un tipo a un método que toma "Largo". Cualquier ayuda por favor.


Como ya se ha mencionado, getOrElse es probablemente lo que está buscando al responder a su pregunta directamente.

Tenga en cuenta también que para convertir a una opción puede simplemente:

val myOption = Option(1)

myOption ahora será un poco (1)

val myOption = Option(null)

myOption ahora será None.


Debe decidir qué sucede cuando la opción es None . ¿Proporcionas un valor por defecto?

def unroll(opt: Option[Long]): Long = opt getOrElse -1L // -1 if undefined unroll(None) // -> -1

También podrías lanzar una excepción:

def unroll(opt: Option[Long]): Long = opt.getOrElse(throw new IllegalArgumentException("The option is expected to be defined at this point") ) unroll(None) // -> exception

En el caso, absténgase de usar null , a menos que tenga muy buenas razones para usarlo ( opt.orNull ).


En primer lugar, su implementación de "lo contrario" tiene algunos problemas serios. Al poner un parámetro de tipo llamado Long en el método, se está siguiendo el tipo Long de la biblioteca estándar. Probablemente te refieres a lo siguiente:

def toOption(value: Long): Option[Long] = if (value == null) None else Some(value)

Incluso esto no tiene sentido (ya que scala.Long no es un tipo de referencia y nunca puede ser null ), a menos que se esté refiriendo a java.lang.Long , que es una receta para el dolor y la confusión. Finalmente, incluso si estuviera tratando con un tipo de referencia (como String ), sería mejor que escribiera lo siguiente, que es exactamente equivalente:

def toOption(value: String): Option[String] = Option(value)

Este método devolverá None si y solo si el value es null .

Para responder a su pregunta, supongamos que tenemos el siguiente método:

def foo(x: Long) = x * 2

Por lo general, no debería pensar en términos de pasar una Option[Long] a foo , sino de "elevar" foo a la Option través del map :

scala> val x: Option[Long] = Some(100L) x: Option[Long] = Some(100) scala> x map foo res14: Option[Long] = Some(200)

El punto principal de la Option es modelar (a nivel de tipo) la posibilidad de un valor "nulo" para evitar toda una clase de problemas NullPointerException -y. El uso del map en la Option permite realizar cálculos sobre el valor que puede haber en la Option mientras continúa modelando la posibilidad de que esté vacío.

Como señala otra respuesta, también es posible usar getOrElse para "rescatar" la Option , pero esto generalmente no es el enfoque idiomático en Scala (excepto en los casos en que realmente hay un valor predeterminado razonable).


Este método ya está definido en la Opción [A] y se llama obtener :

scala> val x = Some(99L) x: Some[Long] = Some(99) scala> x.get res0: Long = 99

El problema es que llamar a get on None lanzará una excepción NoSucheElement:

scala> None.get java.util.NoSuchElementException: None.get

por lo tanto, no obtendrá ningún beneficio al usar un tipo de Opción.

Por lo tanto, como se indicó antes, puede usar getOrElse si puede proporcionar un valor predeterminado razonable o manejar la Excepción.

La forma idiomática de la escala sería utilizar un mapa o una comprensión.

x map (_ + 1) res2: Option[Long] = Some(100)

o

for (i <- x) yield i +1 res3: Option[Long] = Some(100)


La opción es una forma de localizar efectos secundarios (su función puede devolver un valor vacío). Y buen estilo para elevar su cálculo a Opción (la opción es Mónada con métodos de mapa y mapa plano ).

val x = Option[Long](10) x.map { a => a + 10 }

Y extraer el valor con el procesamiento manual del efecto secundario:

val res = x match { case Some(a) => s"Value: $a" case None => "no value" }


Si tienes x como opción [Long], x.get te dará Long.