Guia Completo de Segurança Nula em Kotlin

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á.