método de envolver nulo regresar en Java con la opción de Scala?
-
11-10-2019 - |
Pregunta
Supongamos que tengo un método session.get(str: String): String
pero no sé si le devolverá una cadena o un valor nulo, porque viene de Java.
¿Existe una manera más fácil de tratar esto en Scala en lugar de session.get("foo") == null
? Tal vez un poco de magia se aplica como ToOption(session.get("foo"))
y luego me puede tratar la información de manera Scala como
ToOption(session.get("foo")) match {
case Some(_) =>;
case None =>;
}
Solución
método Option
El compañero de objeto apply
sirve como una función de conversión de referencias anulables:
scala> Option(null)
res4: Option[Null] = None
scala> Option(3)
res5: Option[Int] = Some(3)
Otros consejos
El objeto Option
tiene una apply
method que hace exactamente eso:
var myOptionalString = Option(session.get("foo"));
Tenga en cuenta que cuando se trabaja con objetos Java no va a funcionar como se espera:
val nullValueInteger : java.lang.Integer = null
val option: Option[Int] = Option(nullValueInteger)
println(option) // Doesn't work - zero value on conversion
val nullStringValue : String = null
val optionString: Option[String] = Option(nullStringValue)
println(optionString) // Works - None value
Este es un tema muy antiguo, pero un buen uno!
Es cierto que la conversión de cualquier resultado no excepción de Trata de opción resultará en una Algunos ...
scala> Try(null).toOption
res10: Option[Null] = Some(null)
Trate ... porque no se trata de cheques nulabilidad pero sólo una forma de manejar funcionalmente excepciones.
El uso de tratar de atrapar una excepción y que la conversión a una opción por conveniencia sólo mostrará Ninguno en caso de una excepción ocurre.
scala> Try(1/0).toOption
res11: Option[Int] = None
Se desea conservar los valores que salen de intento. Eso puede ser nulo.
Pero también es cierto que la lib estándar es bastante confuso a veces ...
scala> Try(null).toOption
res12: Option[Null] = Some(null)
scala> Option(null)
res13: Option[Null] = None
Este comportamiento es un poco inconsistente, pero es como que refleja el uso de ambos intented Trate de Opción.
Se utiliza tratar de conseguir lo que salga de una expresión que puede lanzar excepciones, y que no se preocupan por la propia excepción.
El valor que puede salir muy bien puede ser un valor nulo. Si toOption dio Ninguno, no pudo estudio diferencial entre una excepción y un nulo , y que no es bonita!
Autónomo, utiliza la opción de encapsular la existencia o no de algo. Así que en ese caso Algunos (nulo) hay ninguno, y eso tiene sentido, porque nula en este caso representa la ausencia de algo. No hay ninguna ambigüedad.
Es importante remarcar que en cualquier caso la transparencia referencial no se rompe desde .toOption es no lo mismo que la opción ()
Si realmente necesita para hacer cumplir AMBOS Seguridad excepción y seguridad nula, y su código de realmente no necesita estudio diferencial entre nulo y una excepción , sólo tiene que combinar ambos paradigmas! Pues bien, eso es lo que quiere, ¿verdad?
Puede hacerlo de una manera ...
scala> Try(Option(null)).getOrElse(None)
res23: Option[Null] = None
scala> Try(Option(3/0)).getOrElse(None)
res24: Option[Int] = None
scala> Try(Option(3)).getOrElse(None)
res25: Option[Int] = Some(3)
... o en otro ...
scala> Try(Option(null)).toOption.flatten
res26: Option[Null] = None
scala> Try(Option(3/0)).toOption.flatten
res27: Option[Int] = None
scala> Try(Option(3)).toOption.flatten
res28: Option[Int] = Some(3)
... o la ridículamente feo de ellos Anothers ...
scala> Option(Try(null).getOrElse(null))
res29: Option[Null] = None
scala> Option(Try(3/0).getOrElse(null))
res30: Option[Any] = None
scala> Option(Try(3).getOrElse(null))
res31: Option[Any] = Some(3)