Detalhes avançados sobre kotlin

Paulo Enoque
Kotlin para Android
5 min readJan 1, 2018

--

Provavelmente esse seja o ultimo artigo da serie kotlin para android antes de tocar sobre especificidades da integração com o android, neste artigo vou abordar os últimos detalhes “importantes” para que você possa escrever qualquer tipo de código usando kotlin. Vou falar sobre loops, nulabilidade, colecções, extension function e infix.

Loops

Os ciclos while e do-while, não trazem nada de especial, pelo que são usados exactamente da mesma forma que no java, então não darei atenção para esses loops. O ciclo for já trás uma abordagem diferente da do java, ele é bem mais parecido com o for-each do java.

O ciclo for pode ser usado nos seguintes caso:

1. Iteração de coleções

2. Iteração de ranges

Para perceber melhor o conceito de ranges vamos a um exemplo, vamos criar um ciclo que imprime todos os números ímpares de 1 a 10:

for (i in 1..10){
if (i%2 != 0) print(i)
}

Podemos perceber que criamos um range (de 1 ate 10 num intervalo fechado), para tornar isso mais interessante, agora vamos mudar o passo do exemplo acima para 2 em vez de 1, o que quer dizer que a contagem será 1,3,5…9:

for (i in 1..10 step 2){    if (i%2 != 0) print(i )}

existem mais detalhes sobre o ciclo for, mas com isso já temos o básico.

Nulabilidade

Aqui vai um tema que todos estavam a espera, como o kotlin nos ajuda quando o assunto são objectos nulos??? simples, por defeitos todos os objectos no kotlin são tipos não nulos, ou seja, não podemos inicializar nem atribuir valores nulos para essas variáveis, se precisar usar variáveis ou propriedades que suportam valores nulos deve dizer explicitamente com o marcador (?):

val nome: String = null

essa expressão vai dar erro de compilação, porque String não pode receber nenhum valor nulo por defeito, para que isso funcione temos que dizer explicitamente ao compilador que queremos com que valores nulos sejam aceites:

val nome: String? = null

agora sim, essa expressão é perfeitamente valida, mas agora temos algo a analisar, como é que o compilador resolve os NullPointerExceptions que podem ocorrer quando tentamos chamar algum método num objecto que pode assumir valores nulos? Como por exemplo:

val nome: String? = null
nome.toUpperCase()

nesse caso o compilador vai dar um erro, nos avisando que não estamos a efectuar uma chamada segura, para resolver o problema devemos verificar se o objecto e nulo ou não:

val nome: String? = null
if (nome != null) nome.toUpperCase()

assim como o compilador já tem certeza que o objecto não é nulo, não dará nenhum erro. Mas deve existir uma maneira mais elegante, seria muito trabalhoso sempre que precisar chamar algum método ter que colocar uma verificação do tipo if, o código fica até um certo ponto mais verboso. Ktolin trás uma maneira mais simples de efectuar essa verificação, usando o elvis operator (?.):

val nome: String? = null
nome?.toUpperCase()

agora ficou mais simples nem… o que acontece é simples se o objecto não for nulo ele vai executar o método desejado, mas se for a expressão vai retornar null, evitando dessa forma o NullPoiterException.

Colecções

As colecções usadas em kotlin são exactamente as mesmas que as do java ou seja, kotlin não tem colecções próprias, abaixo mostro as colecções mais usadas e um exemplo de implementação:

// Arrays
val array = arrayOf(1, 2, 3)
// ArrayList
val arrayList = arrayListOf(1, 2, 3)
// List
val lista = listOf(1, 2, 3)
// HashMaps
val mapas = mapOf(“um” to 1, “dois” to 2, “tres” to 3)

Por defeito todas as colecções criadas acima são imutáveis, ou seja, uma vez instanciadas não pode-se adicionar, remover o alterar o valor dos seus elementos, se desejar usar as versões mutáveis deve fazer o seguinte:

// List
val lista = mutableListOf(1, 2, 3)

Podemos ver acima que usamos a versão mutável de uma lista:

Iteração em coleções

Existem duas formas básicas de iterações em colecções, usando ciclo for, ou iteração interna:

Usando ciclo for:

val lista = mutableListOf(1, 2, 3)
for (elemento in lista){
print(“$elemento “)
}

para quem já vem usando o forech deve estar bem familiarizado com essa abordagem.

Usando iteração interna:

lista.forEach { elemento -> print(“$elemento “) }

nessa abordagem é importante que já esteja familiarizado com o conceito das expressões lambdas.

extension function

E finalmente para aquela que é uma das melhores novidade que o kotlin trás, as extension function permitem adicionar funcionalidade a qualquer biblioteca ou classe sendo essa biblioteca ou classe da sua autoria ou não, para simplificar vamos a um exemplo, imagine que pretende adicionar a classe Int (do kotlin) a funcionalidade multipucadoPor(valor: Int):

fun Int.multiplicado(valor: Int) = this * valor
print(2.multiplicado(2))

analisado o código acima podemos perceber que:

1. Para declara uma extension function separamos o nome da classe (Int) e o nome da função (multiplicadoPor) por um ponto(.);

2. This representa o elemento que irá chamar a função que criamos

3. Explicando de maneira simples o exemplo acima, quando um objecto do tipo Int (no exemplo temos o numero 2) chama o método multiplicadoPor esse a função retorna o valor desse objecto multiplicado pelo valor fornecido como argumento.

infix

Esta também é uma novidade, todos nós sabemos que prefixos são elementos que são colocados antes das palavras para lhes dar significado, sufixos são elementos que são colocados logo depois das palavras para lhes dar significado o mesmo acontece com infix (na verdade são infixos) elementos que colocados no meio das palavras para lhes dar significado, para perceber melhor o conceito vamos fazer algumas alterações no exemplo passado:

infix fun Int.multiplicado(valor: Int) = this * valor
print(2 multiplicado 2)

analisado o código acima podemos perceber que:

1. Para criar um infix colocamos o marcador infix antes do marcador fun;

2. É obrigatório que as funções em infix tenham apenas um parâmetro;

3. As funções infix podem ser chamadas sem separar o objecto que chama a função da função por um ponto, e também não precisamos colocar o argumento entre parênteses, o que torna a linguagem mais concisa, porque deixa bem claro o que o programador deseja fazer;

4. Infix podem ser usados em extension functions;

Chegou o fim de mais um artigo, todos os conceitos básicos de programação já foram abordados na serie, o que quer dizer que o próximo artigo já vamos colocar a mão na massa na integração da linguagem com o Android, se tiver qualquer duvida não pense duas vezes em me contactar por:

Email: pauloenoque2014@gmail.com

Whatsapp: +258823389250

Não esqueça de dar os clpas de sempre para que mais pessoas tenham acesso ao material, obrigado pela sua atenção.

--

--