Uma breve introdução a Kotlin
Vamos aprender o básico da mais nova linguagem oficial do Android?
Desde o Google I/O 2017, evento no qual Kotlin foi anunciada como a primeira linguagem a ganhar suporte oficial para Android desde seu advento, a linguagem se tornou alvo de muita discussão. Tendo adquirido um peso maior no mercado, claro que viriam mais artigos sobre, então vamos lá!
Para começar: sendo Kotlin uma linguagem para a JVM, esta já vinha sendo bastante utilizada para plataformas que tivessem como base a JVM, i.e., embora o suporte oficial seja novidade, a linguagem já estava sendo abraçada pela comunidade Android. A Google, em parceria com a Jetbrains, já está trabalhando para melhorar a experiência do desenvolvedor com a linguagem. Você pode ler um pouco sobre a criação da linguagem neste artigo.
Kotlin não é a única linguagem interoperável com Java: temos grandes exemplos, como Scala, Groovy, Clojure, além de uma enorme gama. A seguir veremos que Kotlin não se parece tanto com Java, então o aprendizado pode requerer algum esforço do aprendiz. O objetivo deste artigo não é ensinar Kotlin, mas introduzir a linguagem, de modo que o leitor que já programa em Java possa entender e decidir se quer ou não se aprofundar na linguagem. Então vamos ao código!
Do que preciso
A IntelliJ Idea já vem com suporte à linguagem, então não há muito com que se preocupar, mas se estiver sentindo dificuldade, siga o passo-a-passo da JetBrains.
Caso prefira o Eclipse, sem problema! Existe um plugin para garantir o bom funcionamento da linguagem na IDE. Basta seguir este tutorial.
O que interessa
Como Java, Kotlin precisa ter uma função main, então podemos dar uma olhada nas primeiras diferenças entre as linguagens. Vamos ver como podemos declarar a função principal em Kotlin:
fun main(args: Array<String>) { print("Hello, world!") }
Mais fácil ou mais difícil que o nosso public static void main(String[] args)? Não existe muito segredo na sintaxe, mas vamos por partes:
* fun é a palavra-chave para declarar uma função em Kotlin e deve ser seguida pelo nome da função.
* Entre parênteses vêm os parâmetros, que devem obedecer ao seguinte formato:
<nome>: <tipo>
* "Array<String>" é de fácil entendimento para quem tem background em Java: significa um Array que recebe objetos do tipo String. Aqui utilizamos Generics e é equivalente a "String[]".
* Abrimos um bloco de código e printamos "Hello, World!".
Agora rode seu código e você deve ver "Hello, World!" no output
Variáveis
Legal! Vamos para a parte mais básica sobre aprender uma nova linguagem? Como podemos armazenar variáveis? Quero criar uma variável peso de valor 75 e imprimi-la, então podemos utilizar a seguinte sintaxe:
var peso = 75 print(peso)
Legal! Sempre podemos nos lembrar de Javascript na hora de declarar nossas variáveis.
Perceba que não informamos o tipo da variável, o que sempre precisamos fazer em Java. Em Kotlin, podemos deixar esse trabalho para o compilador, de modo que o tipo é inferido a partir do valor que atribuímos. Mas também podemos fazer o seguinte:
var peso: Int peso = 3
Podemos inicializar nossas variáveis em um ponto posterior no nosso código, informando seu tipo, mas para utilizá-las o compilador precisa ser capaz de provar que estas já foram inicializadas. Ou seja:
var peso: Int if (algumaCondicionalObscura) { peso = 70 } else { peso = 60 } print(peso) // Agora sim!
Kotlin também traz o conceito de variáveis assign-once ou read-only. Nos basta trocar a keyword da declaração:
val peso: Int peso = 40
E ao tentarmos atribuir um novo valor:
peso = 50 // Error: Val cannot be reassigned
Os tipos básicos de Kotlin são:
- Double
- Float
- Long
- Int
- Short
- Byte
- Char
- Boolean
- Array
- String
Caso queira ler mais sobre estes, basta ir na respectiva seção da documentação.
Controle de fluxo
Kotlin possui os controles com os quais já estamos acostumados, com algumas features a mais para nos ajudar.
If
Em Kotlin, o if se parece bastante com o que já conhecemos:
if (altura > 1,9) { print("Gigante!") } else { print("Normal.") }
Ou...
if (altura > 1,9) print("Gigante!") else print("Normal.")
Vamos criar um caso? Vamos escrever um programa para nos dizer qual Jedi tem a maior altura:
val alturaYoda = 0.66 val alturaAnakin = 1.88 val maiorAltura: Double if (alturaYoda > alturaAnakin) maiorAltura = alturaYoda else maiorAltura = alturaAnakin
Ficou meio estranho, né?! Pois estou prestes a lhes mostrar o pulo do gato que a linguagem nos oferece.
Em Kotlin, if é uma expressão, ou seja, retorna um valor. Sendo assim, podemos reescrever nosso código da seguinte forma:
val alturaYoda = 0.66 val alturaAnakin = 1.88 val maiorAltura = if (alturaYoda > alturaAnakin) alturaYoda else alturaAnakin // aqui if é usado como uma expressão
Também podemos envolver os statements com chaves, utilizando a sintaxe padrão:
val maiorAltura = if (alturaYoda > alturaAnakin) { alturaYoda } else { alturaAnakin }
When
Em Kotlin, a keyword when provê uma "versão avançada" do switch que conhecemos no Java. Vamos ver como funciona?
val i = 2 when (i) { 1 -> print("É pouco!") 2 -> print("É muito!") 3, 4 -> print("É demais!") // Duas condições combinadas else -> { print("Não se aplica :/") // Atenção ao bloco de código } }
A menos que o compilador consiga provar que todos os casos possíveis já foram tratados, a cláusula else será necessária: se não declará-la, receberá um erro de compilação.
Mas aqui temos um pulo do sapo. Não somos obrigados a passar um valor para o comando, pois podemos utilizar valores dos escopos superiores para criar Booleans nas cláusulas:
// Em centímetros \/ when { altura in 120..150 -> print("Um anão minerador, barbudo e parrudo!") // Acima temos um intervalo. 'in' verifica se o valor está dentro do intervalo de 120 a 150. altura < 120 -> print("Um hobbit do Condado... Brandebuque?") altura > 150 -> print("Provavelmente um humano...") }
Aqui utilizamos when de maneira parecida com uma cadeia de if-else if, mas de maneira um tanto mais elegante (opinião própria). Note que acima não precisamos inserir uma cláusula else, pois para qualquer possível valor de altura, existe uma cláusula que o cobre.
Legal, já vimos que when é bastante poderoso, mas estou prestes a lhes mostrar o pulo do gato parte II! Como o if, when também pode ser tratado como uma expressão:
val altura = 170 val raça = when { altura in 120..150 -> "Anão" altura < 120 -> "Hobbit" altura > 150 -> "Humano (provavelmente)" else -> throw IllegalArgumentException("Altura não é válida") } print(raça) // Output: Humano (provavelmente)
Note que acima tivemos de declarar a cláusula else, apesar de não precisarmos: quando utilizamos when como uma expressão, precisamos imprescindivelmente declarar uma cláusula else.
For
O for de Kotlin percorre qualquer coisa que provenha um iterator. Sem entrar em detalhes, coleções e intervalos são os consumos mais comuns do for. Eis a sintaxe básica:
for (item: Tipo in coleção) { // whatever pleasures you }
Também podemos percorrer com o valor do índice!
for ((indice, valor) in coleção.withIndex()) { // whatever pleasures you with index }
While
No while, não temos nada de novo, pois o while e o do..while funcionam como no Java, mas vale demonstrar:
var x = 10 while (x > 0) { x-- } do { x++ } while (x < 10)
Ranges
Outra coisa bacana de Kotlin, que não é exatamente uma novidade, mas vem sendo implementado na maioria das linguagens modernas, é a funcionalidade dos ranges, traduzidos literalmente para intervalos. Podemos facilmente criar um intervalo com o operador ..
e percorrer o mesmo com um for:
for (i in 1..5) print(i) // Imprime 12345
Também temos muitas infix functions para a criação de intervalos:
for (i in 5 downTo 1) print(i) // 54321 // Cria um intervalo decrescente for (i in 1..10 step 2) print(i) // 13579 // Cria um intervalo que incrementa 2 em vez de 1 for (i in 1 until 10) print(i) // 123456789 // Cria um intervalo que não inclui o 10
Como vimos acima, temos uma maneira de verificar se um valor está incluído num intervalo:
if (altura in 150..200) print("Um humano, talvez um elfo?")
Null safety
Ah, quem nunca levou um NullPointerException que atire a primeira pedra! A referência nula, conhecida como "The billion dollars mistake", pode nos causar muita dor de cabeça. Não à toa, seu criador, Tony Hoare, pediu desculpas em público em 2009. Pois bem, pessoalmente acho essa feature a mais fantástica, em Kotlin.
O sistema de tipos de Kotlin visa eliminar o perigo de referências nulas no código, abrindo espaço para o que é chamado na computação de null safety.
Kotlin distingue referências que podem receber null (Nullable) das que não podem. Uma variável como as que estávamos declarando anteriormente não pode receber null:
var string: String string = null // Erro de compilação!
Para declarar uma variável nullable, nos basta adicionar '?' no tipo:
var stringNullable: String? string = null // Ok
Então aqui fica divertido: o compilador nos impede de acessar diretamente qualquer propriedade de uma referência nullable:
var tamanhoDaString: Int = stringNullable.length // error: variable 'stringNullable' can be null
Isso acontece porque não seria seguro acessá-la, uma vez que ela pode conter null, que nos jogaria um NPE. Ou seja, somos obrigados a tratar a possibilidade da referência conter null: essa é a essência de null safety.
Mas precisamos acessar aquela propriedade, então dispomos de algumas maneiras de fazer isso.
Primeiro, podemos checar explicitamente se ela carrega null em uma condicional:
var tamanhoDaString: Int = if (stringNullable != null) stringNullable.length else -1
Ou podemos usar o operador de safe call ('?'), que faz a expressão inteira retornar null caso a referência em questão seja nula:
var tamanhoDaString: Int = stringNullable?.length // Erro // Type mismatch: inferred type is Int? but Int was expected
Ops! O tipo de nossa variável tamanhoDaString era Int, mas a expressão retornou o tipo Int?. Faz sentido! Se a nossa expressão pode retornar null, temos de atribuí-la a uma referência nullable:
var tamanhoDaString: Int? = stringNullable?.length // Ok
Conclusão
Que linguagem legal, não?! O mais legal ainda é que o que eu mostrei aqui é muito pouco: Kotlin tem muito a se explorar e é difícil dominar todas suas features e "pulos do gato". Contudo, a curva de aprendizagem é relativamente baixa. É um ótimo investimento do seu tempo, principalmente se pretendes ser ou já é um desenvolvedor Android. Além de tudo, convenhamos: quem não fica empolgado aprendendo uma nova linguagem? Pessoalmente, eu AMO aprender novas linguagens, tecnologias, conceitos, etc.
Se quiser continuar a estudar Kotlin, recomendo a documentação da linguagem: é boa, simples, sucinta e explicativa.
Obrigado por ler & happy coding!
Desenvolvedor na TriadWorks