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 to pola obowiązkowe w Account
. Jak w idiomatyczny sposób przeprowadzasz kontrole zerowe?
Odpowiedzi:
4 dla odpowiedzi № 1Możesz użyć Option
typ do obsługi null
wartości. Po prostu zawijaj wartość zerową Option
a następnie możesz dopasować wzór na nim lub coś innego. W twoim przykładzie myślę, że najbardziej zwięzłym sposobem na połączenie 4 wartości zerowalnych jest zrozumienie:
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)
}
}
EDYTOWAĆ
Kolejna sprawa to _.toDouble
konwersja, która może zgłosić wyjątek, jeśli nie uda się go przeanalizować, aby można go było owinąć Try
zamiast tego (zaktualizowałem kod powyżej).
EDIT2
Aby wyjaśnić, co się tutaj dzieje:
- kiedy otoczysz wartość
Option
staje sięNone
jeśli wartość jestnull
, lubSome(...)
z inną wartością - podobnie podczas owijania czegoś, co może spowodować wyjątek
Try
, staje się alboFailure
z wyjątkiem lubSuccess
z wartością toOption
metoda konwertujeTry
doOption
w prosty sposób:Failure
staje sięNone
,Success
staje sięSome
- w rozumieniu jeśli każdy z czterech
Option
s zwracaNone
(tj. jednym z nich byłnull
nie udało się przeanalizować liczby), zwraca całą instrukcjęNone
i tylko jeśli każdy z czterech daje wartość, są one przekazywane doYellowAccount
konstruktor
0 dla odpowiedzi nr 2
Jak sugeruje druga odpowiedź, możesz użyć Option
do obsługi możliwych wartości zerowych. Nie możesz użyć for
zrozumienie sposobu, w jaki jest tam sugerowany, ale jest kilka sposobów obejścia tego. Najłatwiej chyba jest .zip
dwie opcje razem, a następnie odwzoruj wynik:
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
)
}