Erick Giorgio
Posted on May 27, 2022
Neste post veremos como o tipo Optional compara e traduz para tipos nullable em Kotlin.
Optional/Nullable Propriedades e tipos de retorno
Em Java, uma propriedade Optional pode ser declarada da seguinte forma:
public interface Person {
String getName();
Optional<Integer> getAge();
}
Em vez de usar o tipo Optional, em Kotlin vamos apenas declarar a propriedade age como anulável:
interface Person {
val name : String
val age : Int?
}
Optional.map() vs. Safe-Call Operator
O método map() do tipo Optional pode ser usado para acessar as propriedades da instância encapsulada de uma maneira “empty-safe
”.
public interface Car {
Person getDriver();
}
Optional<Car> car = getNextCarIfPresent();
Optional<Integer> driversAge =
car.map(Car::getDriver).flatMap(Person::getAge);
Este trecho de código recupera o motorista de um carro opcional e, em seguida, recupera a idade opcional desse motorista. Como ambos, o carro e a idade são opcionais, somos forçados a usar o método flatMap() ao recuperar a idade do motorista. Em Kotlin, podemos usar o operador de chamada segura embutido ?. para acessar propriedades de tipos Nullable :
interface Car {
val driver: Person
}
val car: Car? = getNextCarIfPresent()
val driversAge: Int? = car?.driver?.age
Optional.map() vs. let() Function
Às vezes, queremos usar um método externo dentro da cadeia de chamadas seguras no tipo Optional. Com o tipo Optional do Java, o mesmo método map()
pode ser usado para esta finalidade:
Optional<DriversLicence> driversLicence =
car.map(Car::getDriver).map(licenceService::getDriversLicence);
Em Kotlin, teremos que usar a função let() do stdlib para invocar funções externas dentro de uma cadeia de operadores de chamada segura para atingir o mesmo objetivo.
val driversLicence: DriversLicence? = car?.driver?.let {
licenceService.getDriversLicence(it)
}
Optional.orElse() vs. Elvis Operator
Quando recuperamos o valor encapsulado por um Optional, geralmente queremos fornecer um valor de fallback. Isso é obtido usando o método *orElse()*
do tipo Opcional :
boolean isOfLegalAge =
car.map(Car::getDriver).flatMap(Person::getAge).orElse(0) > 18;
Quando a cadeia de chamadas de mapa retornar uma idade não vazia, ela será usada. Caso contrário, o valor de fallback fornecido 0 será usado. Kotlin tem o elvis Operator ?: para este propósito:
val isOfLegalAge: Boolean = car?.driver?.age ?: 0 > 18
Optional.filter() vs. takeIf() Function
O tipo opcional fornece o método filter()
, que pode ser usado para verificar uma condição no valor encapsulado. Se a condição for satisfeita pelo valor encapsulado, o método de filtro retornará o mesmo objeto Optional. Caso contrário, retornará um objeto Optional vazio.
Optional<Person> illegalDriver =
car.map(Car::getDriver).filter(p -> p.getAge().orElse(0) < 18);
Em Kotlin, usamos a função takeIf() do stdlib e acabamos com muito menos código:
val ilegalDriver: Pessoa? = carro?.motorista ?. takeIf { it.idade ?: 0 < 18 }
Optional.ifPresent() vs. let() Function
Ao final da conversão e filtragem do valor Optional, geralmente queremos usar o valor encapsulado em algum cálculo ou código. Para isso, o tipo Optional fornece o método ifPresent()
:
car.map(Car::getDriver)
.filter(person -> person.getAge().orElse(0) < 18)
. ifPresent (illegalDriver -> {
checkIdentity(illegalDriver);
putInJail(illegalDriver);
});
Em Kotlin, usaríamos novamente a função let() para isso:
car?.driver?.takeIf { it.age ?: 0 < 18 }?.let { illegalDriver ->
checkIdentity(illegalDriver)
putInJail(illegalDriver)
}
Kotlin fornece uma variedade de operadores integrados e funções stdlib que simplificam o manuseio de tipos anuláveis. Usá-los leva a um código curto, conciso e legível, especialmente quando combinado em cadeias de chamadas mais longas.
Além do código mais legível, os tipos anuláveis do Kotlin têm várias vantagens sobre o tipo Optional do Java.
Primeiro, não há sobrecarga de tempo de execução envolvida ao usar tipos anuláveis em Kotlin¹. Ao contrário de Opcional, nenhum objeto wrapper é criado para agrupar o valor real.
Em segundo lugar, os tipos anuláveis em Kotlin fornecem segurança nula em tempo de compilação. Usá-los de maneira não segura levará a um erro em tempo de compilação. Por outro lado, usar o tipo Optional de maneira não segura não é verificado pelo compilador e levará a uma exceção de tempo de execução.
a menos que estejamos lidando com tipos primitivos anuláveis, caso em que a versão em caixa do tipo primitivo é usada no nível da JVM.
Referência
https://docs.google.com/spreadsheets/d/1P2gMRuu36pSDW4fdwE-fLN9fcA_ZboIU2Q5VtgixBNo/edit#gid=0
https://www.zup.com.br/blog/java-vs-kotlin-vantagens-desvantagens
Posted on May 27, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 19, 2024
November 18, 2024