/ / ¿Cómo hacer cheques nulos en Scala de forma idiomática? - Scala

¿Cómo hacer comprobaciones nulas en Scala de forma idiomática? - Scala

case class Account(
val name: String,
val uuid: String,
val lat: Double,
val lng: Double
)
}

object Account {
def create(row: Row): Option[YellowAccount] = {
val name = row.getAs[String]("store_name")
val uuid = row.getAs[String]("uuid")
val latO = row.getAs[String]("latitude")
val lngO = row.getAs[String]("longitude")

// How do you do null checks here in an idiomatic way?
if (latO == null || lngO == null) {
return None
}

Some(YellowAccount(name, uuid, latO.toDouble, lngO.toDouble))
}

}

lat / long son campos obligatorios en Account. ¿Cómo haces cheques nulos de forma idiomática?

Respuestas

4 para la respuesta № 1

Puedes usar Option tipo para manejar null valores. Usted simplemente envuelve un valor anulable en Option y luego puedes hacer un patrón de coincidencia en él o en otra cosa. En su ejemplo, creo que la forma más concisa de combinar 4 valores anulables es para la comprensión:

import scala.util.Try

object Account {
def create(row: Row): Option[YellowAccount] = {
for {
name <- Option( row.getAs[String]("store_name") )
uuid <- Option( row.getAs[String]("uuid") )
latO <-    Try( row.getAs[String]("latitude").toDouble ).toOption
lngO <-    Try( row.getAs[String]("longitude").toDouble ).toOption
} yield
YellowAccount(name, uuid, latO, lngO)
}
}

EDITAR

Otra cosa aquí es _.toDouble conversión, que puede generar una excepción si no puede analizar la cadena, por lo que puede envolverla Try en su lugar (actualicé el código anterior).

EDIT2

Para aclarar lo que está pasando aquí:

  • cuando envuelves un valor en Option se vuelve None si el valor es null, o Some(...) con el valor de lo contrario
  • de manera similar cuando se envuelve algo que puede generar una excepción en Try, se convierte en cualquiera Failure con la excepción, o Success con el valor
  • toOption método convierte Try a Option De una manera directa: Failure se convierte None, Success se convierte Some
  • en la para-comprensión si alguna de los cuatro Options devuelve None (es decir, uno de ellos era null de no analizar un número), devuelve la declaración completa Noney solo si cada de los cuatro produce un valor, se pasan a la YellowAccount constructor

0 para la respuesta № 2

Como la otra respuesta sugiere, puedes usar Option para manejar posibles nulos. No puedes usar for Comprensión de la forma en que se sugiere allí, pero hay varias formas de evitarlo. Lo más fácil, probablemente es .zip las dos opciones juntas, y luego mapear sobre el resultado:

  Option(row.getAs[latitude])
.zip(Option(row.getAs[String]("longitude")))
.map { case (lat, long) =>
YellowAccount(
row.getAs[String]("store_name"),
row.getAs[String]("uuid"),
lat.toDouble,
long.toDouble
)
}