As opçÔes em scala sĂŁo muito Ășteis e ajudam a especificar explicitamente se seus mĂ©todos podem nĂŁo retornar nenhum valor (onde vocĂȘ retornaria null
em Java) e quando os parĂąmetros sĂŁo opcionais.
Por exemplo, vocĂȘ pode ter um endpoint REST com algo assim:
def users(nameFilter: Option[String], cityFilter: Option[String])
As opçÔes são geralmente gerenciadas com match
, map
e flatMap
, ou para compreensĂ”es. Mas imagine que vocĂȘ queira fazer um teste simples, para saber se vocĂȘ tem pelo menos um filtro, match
seria complicado, pois vocĂȘ terĂĄ que definir muitos casos. Mas vocĂȘ pode fazer isso com um teste simples:
val withFilter = nameFilter.isDefined || cityFilter.isDefined
Se vocĂȘ começar a fazer isso com muitas opçÔes, acabarĂĄ com muito isDefined
e seu cĂłdigo se tornarĂĄ um pouco menos legĂvel do que poderia ser. NĂŁo seria bom se vocĂȘ pudesse apenas fazer nameFilter || cityFilter
:, afinal as opçÔes sĂŁo muito semelhantes aos booleanos, elas sĂŁo “verdadeiras” (definidas) ou nĂŁo.
Com a conversĂŁo implĂcita de scala, isso Ă© muito simples, podemos apenas converter a opção em booleano:
implicit def optToBool(opt: Option[_]): Boolean = opt.isDefined
Isso darĂĄ:
Some(10) || None //> res0: Boolean = true
Some(10) || Some(20) //> res1: Boolean = true
None || Some(20) //> res2: Boolean = true
None || None //> res3: Boolean = false
Some(10) && Some(20) //> res4: Boolean = true
Some(10) && None //> res5: Boolean = false
None && Some(20) //> res6: Boolean = false
None && None //> res7: Boolean = false