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 № 1Puedes 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 vuelveNone
si el valor esnull
, oSome(...)
con el valor de lo contrario - de manera similar cuando se envuelve algo que puede generar una excepción en
Try
, se convierte en cualquieraFailure
con la excepción, oSuccess
con el valor toOption
método convierteTry
aOption
De una manera directa:Failure
se convierteNone
,Success
se convierteSome
- en la para-comprensión si alguna de los cuatro
Option
s devuelveNone
(es decir, uno de ellos eranull
de no analizar un número), devuelve la declaración completaNone
y solo si cada de los cuatro produce un valor, se pasan a laYellowAccount
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
)
}