segundo - ¿Por qué Foreach es mejor que obtener las opciones de Scala?
cuantas consultas por segundo soporta mysql (6)
¿Por qué utilizar foreach
, map
, flatMap
, etc. se considera mejor que usar get
para las opciones de Scala? Si uso isEmpty
puedo llamar para get
seguridad.
Bueno, parece que vuelve a "decir, no preguntar". Considera estas dos líneas:
if (opt.isDefined) println(opt.get)
// versus
opt foreach println
En el primer caso, estás mirando hacia adentro y luego reaccionando dependiendo de lo que ves. En el segundo caso, solo está diciendo opt
lo que quiere hacer, y dejar que se ocupe de ello.
El primer caso sabe demasiado acerca de la Option
, replica la lógica interna, es frágil y propenso a errores (puede generar errores en tiempo de ejecución, en lugar de errores en tiempo de compilación, si se escriben incorrectamente).
Añadir a eso, no es composable. Si tiene tres opciones, una sola para la comprensión se ocupa de ellas:
for {
op1 <- opt1
op2 <- opt2
op3 <- opt3
} println(op1+op2+op3)
Con if
, las cosas comienzan a complicarse rápido.
En pocas palabras:
Si necesita hacer algo (un procedimiento cuando no necesita capturar el valor de retorno de cada invocación) solo si la opción está definida (es decir, es
Some
): useforeach
(si le importan los resultados de cada invocación, usar elmap
)Si necesita hacer algo si la opción se define y otra cosa si no es así: use
isDefined
en una sentencia ifSi necesita el valor si la opción es
Some
, o un valor predeterminado si esNone
: usegetOrElse
Intentar realizar nuestras operaciones con get
es un estilo más imperativo en el que necesitas saber qué hacer y cómo hacerlo . En otras palabras, estamos dictando cosas y profundizando en las Options
internas de Options
. Donde, como map,flatmap
son la forma más funcional de hacer las cosas donde decimos qué hacer, pero no cómo hacerlo .
La razón por la que es más útil aplicar cosas como map
, foreach
y flatMap
directamente a la Option
lugar de usar get
y luego realizar la función es que funciona en alguno o en None
y no es necesario hacer controles especiales para asegurarse el valor está ahí.
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í es una Option[Int]
, que es deseable ya que si x
es opcional, entonces y
podría estar indeterminado. Dado que get
no funciona en None
, tendrías que hacer un montón de trabajo extra para asegurarte de que no hayas tenido ningún error; trabajo extra que se hace por usted por el map
.
Una buena razón para usar foreach
es analizar algo con opciones anidadas. Si tienes algo como
val nestedOption = Some(Some(Some(1)))
for {
opt1 <- nestedOption
opt2 <- opt1
opt3 <- opt2
} println(opt3)
La consola imprime 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, las comprensiones le permiten evitar una "pirámide" gigante de Ninguno / Alguna comprobación.
Ya hay respuestas excelentes para la pregunta real, pero para obtener más Option
, definitivamente debe consultar la Hoja de referencia de Option
Tony Morris .