¡Este es un tema muy antiguo pero agradable!
Es cierto que convertir cualquier resultado que no sea de excepción de Try to Option dará como resultado un Some ...
scala> Try(null).toOption
res10: Option[Null] = Some(null)
... porque Try no se trata de verificar la nulabilidad, sino solo de una forma de manejar funcionalmente las excepciones.
El uso de Intentar detectar una excepción y convertirla en una Opción por conveniencia solo mostrará Ninguno en caso de que ocurra una excepción.
scala> Try(1/0).toOption
res11: Option[Int] = None
Desea conservar los valores que surgen de Try. Eso puede ser nulo.
Pero también es cierto que la librería estándar a veces es bastante confusa ...
scala> Try(null).toOption
res12: Option[Null] = Some(null)
scala> Option(null)
res13: Option[Null] = None
Este comportamiento es un poco inconsistente, pero refleja el uso intencionado de Try y Option.
Usas try para obtener lo que sea que surja de una expresión que pueda generar excepciones, y no te importa la excepción en sí.
El valor que puede aparecer puede muy bien ser nulo. Si toOption dio None, no podría diferenciar entre una excepción y un nulo , ¡y eso no es bonito!
Independiente, usa Option para encapsular la existencia o no de algo. Entonces, en ese caso, Some (null) es None, y eso tiene sentido, porque null en ese caso representa la ausencia de algo. Aquí no hay ambigüedad.
Es importante remarcar que en cualquier caso la transparencia referencial no se rompe ya que .toOption no es lo mismo que Option ()
Si realmente necesita para hacer cumplir AMBOS seguridad de excepción y la seguridad nula, y su código realmente no necesita estudio diferencial entre nulo y una excepción , sólo tiene que combinar ambos paradigmas! Porque bueno, eso es lo que quieres, ¿verdad?
Puedes 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)
... u 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 el ridículamente más feo de ellos otros ...
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)