¿Por qué es mejor que obtener las opciones de Scala?
-
26-10-2019 - |
Pregunta
Por qué usar foreach
, map
, flatMap
etc. se consideran mejor que usar get
¿Para opciones de Scala? Si usoisEmpty
puedo llamar get
sin peligro.
Solución
Bueno, vuelve a "decir, no preguntes". Considere estas dos líneas:
if (opt.isDefined) println(opt.get)
// versus
opt foreach println
En el primer caso, estás mirando por dentro opt
Y luego reaccionando dependiendo de lo que vea. En el segundo caso, solo estás diciendo opt
Lo que quieres hacer y deja que lo lidie.
El primer caso sabe demasiado sobre Option
, replica la lógica interna, es frágil y propensa a los errores (puede dar como resultado errores de tiempo de ejecución, en lugar de errores de tiempo de compilación, si se escribe incorrectamente).
Agregue a eso, no es compuesto. Si tiene tres opciones, una sola para la comprensión se encarga de ellas:
for {
op1 <- opt1
op2 <- opt2
op3 <- opt3
} println(op1+op2+op3)
Con if
, las cosas comienzan a ponerse desordenadas rápidamente.
Otros consejos
Una buena razón para usar foreach
está analizando algo con opciones anidadas. Si tienes algo como
val nestedOption = Some(Some(Some(1)))
for {
opt1 <- nestedOption
opt2 <- opt1
opt3 <- opt2
} println(opt3)
Las impresiones de la consola 1
. Si extiende esto a un caso en el que tiene una clase que opcionalmente almacena una referencia a algo, que a su vez almacena otra referencia, ya que las comprensiones le permiten evitar una "pirámide" gigante de ninguno/algunas verificaciones.
Ya hay excelentes respuestas a la pregunta real, pero para más Option
-Foo definitivamente deberías ver Hoja de trucos de opción de Tony Morris.
La razón por la que es más útil aplicar cosas como map
, foreach
, y flatMap
directamente al Option
En lugar de usar get
y luego realizar la función es que funciona en cualquiera Some
o None
Y no tiene que hacer cheques especiales para asegurarse de que el valor esté allí.
val x: Option[Int] = foo()
val y = x.map(_+1) // works fine for None
val z = x.get + 1 // doesn't work if x is None
El resultado para y
Aquí hay un Option[Int]
, que es deseable ya que si x
es opcional, entonces y
Podría ser indeterminado también. Ya que get
no funciona None
, tendrías que hacer un montón de trabajo adicional para asegurarte de no recibir ningún error; trabajo adicional que se hace por ti por ti map
.
En pocas palabras:
Si necesita hacer algo (un procedimiento en el que no necesita capturar el valor de retorno de cada invocación) solo si la opción está definida (es decir, es un
Some
): usarforeach
(Si le importa los resultados de cada invocación, usemap
)Si necesita hacer algo si la opción se definió y algo más si no es así: use
isDefined
En una declaración IFSi necesita el valor si la opción es un
Some
, o un valor predeterminado si es unNone
: usargetOrElse
Tratando de realizar nuestras operaciones con get
es un estilo más imperativo donde necesitas tel Qué hacer y cómo hacer . En otras palabras, estamos dictando cosas y cavando más en el Options
INTALES. Mientras map,flatmap
son una forma más funcional de hacer cosas donde estamos diciendo Qué hacer pero no cómo hacer.