scala - interna - Obteniendo valor de cualquiera
importancia de la economia de escala (4)
Dado el tipo A
en ambos lados, es decir, Either[A, A]
, podemos usar Either.merge
... para extraer valores de cualquiera de las instancias, independientemente de si son Izquierda o Derecha.
Observe si los tipos izquierdo y derecho difieren, el resultado se convierte en Any
:
val e: Either[Int, String] = Right("hello")
e.merge // hello: Any
Además de usar match
, ¿existe una forma similar a la getOrElse
de getOrElse
o getOrElse
el contenido real del valor Right
o Left
?
scala> val x: Either[String,Int] = Right(5)
scala> val a: String = x match {
case Right(x) => x.toString
case Left(x) => "left"
}
a: String = 5
En Scala 2.12 hay un método getOrElse
para obtener el valor "correcto" pero no se puede usar directamente para el valor "izquierdo". Sin embargo, puede hacerlo así: e.swap.getOrElse(42)
.
La respuesta de Nicolas Rinaudo con respecto a llamar a getOrElse
en la proyección left
o right
es probablemente la más cercana a Option.getOrElse
.
Alternativamente, puede fold
el o bien:
scala> val x: Either[String,Int] = Right(5)
x: Either[String,Int] = Right(5)
scala> val a: String = x.fold(l => "left", r => r.toString)
a: String = 5
Como l
no se usa en el pliegue anterior, también puede escribir x.fold(_ => "left", r => r.toString)
Edición: En realidad, literalmente puede tener Option.getOrElse
llamando a toOption
en la proyección left
o right
de cualquiera de los dos, por ejemplo,
scala> val o: Option[Int] = x.right.toOption
o: Option[Int] = Some(5)
scala> val a: String = o.map(_.toString).getOrElse("left")
a: String = 5
No me gusta ninguno de los dos en particular y, como resultado, no estoy muy familiarizado con el tema, pero creo que estás buscando proyecciones: either.left.getOrElse
: either.left.getOrElse
o either.right.getOrElse
.
Tenga en cuenta que las proyecciones también se pueden utilizar para las comprensiones. Este es un ejemplo directamente de la documentación:
def interactWithDB(x: Query): Either[Exception, Result] =
try {
Right(getResultFromDatabase(x))
} catch {
case ex => Left(ex)
}
// this will only be executed if interactWithDB returns a Right
val report =
for (r <- interactWithDB(someQuery).right) yield generateReport(r)
if (report.isRight)
send(report)
else
log("report not generated, reason was " + report.left.get)