Guia Completo de Segurança Nula em Kotlin
1. Visão geral
Neste artigo, veremos os recursos de segurança nula integrados à linguagem Kotlin. O Kotlin fornece manipulação nativa abrangente de campos anuláveis - nenhuma biblioteca adicional é necessária.
2. Dependência do Maven
Para começar, você precisará adicionar a dependência Mavenkotlin-stdlib ao seupom.xml:
org.jetbrains.kotlin
kotlin-stdlib
1.1.1
Você pode encontrar a versão mais recente emMaven Central.
3. Tipos de referência anuláveis e não anuláveis
Kotlin has two types of references que são interpretados pelo compilador para fornecer ao programador informações sobre a correção de um programa em tempo de compilação - aqueles que são anuláveis e aqueles que não são.
Por padrão, Kotlin assume que o valor não pode sernull:
var a: String = "value"
assertEquals(a.length, 5)
Não podemos atribuirnull à referênciaa e, se você tentar, isso causará um erro do compilador.
If we want to create a nullable reference, we need to create append the question mark(?) to the type definition:
var b: String? = "value"
Depois disso, podemos atribuirnull a ele:
b = null
When we want to access the b reference, we must handle the null case explicitly para evitar um erro de compilação porque Kotlin sabe que esta variável pode conternull:
if (b != null) {
println(b.length)
} else {
assertNull(b)
}
4. Chamadas Seguras
Lidar com todas as referências anuláveis dessa maneira pode ser complicado. Felizmente, Kotlin tem uma sintaxe para “chamadas seguras” - esta sintaxe permite aos programadoresexecute an action only when the specific reference holds a non-null value.
Vamos definir duas classes de dados para ilustrar esse recurso:
data class Person(val country: Country?)
data class Country(val code: String?)
Observe que os camposcountryecode são do tipo de referência anulável.
Para acessar esses campos de maneira fluente, podemos usar a sintaxe de chamada segura:
val p: Person? = Person(Country("ENG"))
val res = p?.country?.code
assertEquals(res, "ENG")
Se a variávelp contiver umnull, a sintaxe das chamadas seguras retornará um resultadonull:
val p: Person? = Person(Country(null))
val res = p?.country?.code
assertNull(res)
4.1. O Método Let ()
Para executar uma ação apenas quando uma referência contém um valor não anulável, podemos usar um operadorlet.
Digamos que temos uma lista de valores e também há um valornull nessa lista:
val firstName = "Tom"
val secondName = "Michael"
val names: List = listOf(firstName, null, secondName)
A seguir, podemos executar uma ação em cada elemento não anulável da listanames usando uma funçãolet:
var res = listOf()
for (item in names) {
item?.let { res = res.plus(it) }
}
assertEquals(2, res.size)
assertTrue { res.contains(firstName) }
assertTrue { res.contains(secondName) }
4.2. O método Also ()
Se quisermos o métodoto apply some additional operation, for example logging on every non-nullable value we can use analso()e encadeá-lo com umlet():
var res = listOf()
for (item in names) {
item?.let { res = res.plus(it); it }
?.also{it -> println("non nullable value: $it")}
}
Ele imprimirá todos os elementos que não sejam nulos:
non nullable value: Tom
non nullable value: Michael
4.3. O Método Run ()
Kotlin tem um métodorun() para executar alguma operação em uma referência anulável. É muito semelhante alet(), mas dentro de um corpo de função, o método Run () operates on this reference instead of a function parameter:
var res = listOf()
for (item in names) {
item?.run{res = res.plus(this)}
}
5. Operador Elvis
Às vezes, quando temos uma referência, queremos retornar algum valor padrão da operação se a referência contivernull. Para conseguir isso, podemos usar um operadorelvis (?:). Isso é equivalente aorElse/orElseGet da classe JavaOptional:
val value: String? = null
val res = value?.length ?: -1
assertEquals(res, -1)
Quando a referênciavalue contém um valor não anulável, o métodolength será invocado:
val value: String? = "name"
val res = value?.length ?: -1
assertEquals(res, 4)
6. Get Nullable Unsafe
Kotlin também tem um operador inseguro para obter um valor de um campo anulável sem lidar explicitamente com a lógica de ausência, mas deve ser usado com muito cuidado.
O operador de ponto de exclamação duplo (!!) pega um valor de uma referência anulável e lança umNullPointerException se ele contémnull. Isso é equivalente à operaçãoOptional.get():
var b: String? = "value"
b = null
assertFailsWith {
b!!.length
}
Se a referência anulável tiver um valor não anulável, a ação nesse valor será executada com sucesso:
val b: String? = "value"
assertEquals(b!!.length, 5)
7. Filtrando valores nulos de uma lista
A classeList em Kotlin tem um método utilitáriofilterNotNull() que retorna apenas valores não anuláveis de uma lista que contém referências anuláveis:
val list: List = listOf("a", null, "b")
val res = list.filterNotNull()
assertEquals(res.size, 2)
assertTrue { res.contains("a") }
assertTrue { res.contains("b") }
Essa é uma construção muito útil que encapsula a lógica que, de outra forma, precisaríamos para implementar a nós mesmos.
8. Conclusão
Neste artigo, exploramos os recursos de segurança nula de Koltin em profundidade. Vimos tipos de referências que podem conter valores denull e aqueles que não podem. Implementamos a lógica de tratamento denull fluente usando os recursos de “chamada segura” e a operadoraelvis.
A implementação de todos esses exemplos e trechos de código pode ser encontrada emGitHub project - este é um projeto Maven, portanto, deve ser fácil de importar e executar como está.