Este codelab faz parte do curso de treinamento do Kotlin para programadores. Você vai aproveitar mais este curso se fizer os codelabs em sequência. Dependendo do seu conhecimento, talvez você possa passar mais rápido por algumas seções. Este curso é destinado a programadores que conhecem uma linguagem orientada a objetos e querem aprender Kotlin.
Introdução
Neste codelab, você vai aprender os conceitos básicos da linguagem de programação Kotlin: tipos de dados, operadores, variáveis, estruturas de controle e variáveis anuláveis e não anuláveis. Este curso é destinado a programadores que conhecem uma linguagem orientada a objetos e querem aprender Kotlin.
Em vez de criar um único app de exemplo, as lições deste curso foram criadas para aumentar seu conhecimento, mas são semi-independentes umas das outras para que você possa ler as seções com que já está familiarizado. Para unificar os exemplos, muitos deles usam um tema de aquário. Se quiser conferir a história completa do aquário, acesse o curso da Udacity Treinamento do Kotlin para programadores (link em inglês).
O que você já precisa saber
- Como criar um projeto no IntelliJ IDEA
- Como abrir e executar código no REPL (Read-Eval-Print Loop) do Kotlin no IntelliJ IDEA (Tools > Kotlin > Kotlin REPL)
O que você vai aprender
- Como usar tipos de dados, operadores e variáveis do Kotlin
- Como trabalhar com booleanos e condições
- A diferença entre variáveis anuláveis e não anuláveis
- Como matrizes, listas e loops funcionam no Kotlin
Atividades deste laboratório
- Trabalhar com o REPL do Kotlin para aprender os conceitos básicos da linguagem
Nesta tarefa, você vai aprender sobre operadores e tipos na linguagem de programação Kotlin.
Etapa 1: conhecer os operadores numéricos
- Abra o IntelliJ IDEA, se ele ainda não estiver aberto.
- Para abrir o REPL do Kotlin, selecione Tools > Kotlin > Kotlin REPL.
Assim como outras linguagens, o Kotlin usa +
, -
, *
e /
para adição, subtração, multiplicação e divisão. O Kotlin também é compatível com diferentes tipos de números, como Int
, Long
, Double
e Float
.
- Insira as seguintes expressões no REPL. Para ver o resultado, pressione
Control+Enter
(Command+Enter
em um Mac) após cada uma.
1+1 ⇒ res8: kotlin.Int = 2 53-3 ⇒ res9: kotlin.Int = 50 50/10 ⇒ res10: kotlin.Int = 5 1.0/2.0 ⇒ res11: kotlin.Double = 0.5 2.0*3.5 ⇒ res12: kotlin.Double = 7.0
Os resultados das operações mantêm os tipos dos operandos. Portanto, 1/2 = 0, mas 1.0/2.0 = 0.5.
- Teste algumas expressões com diferentes combinações de números inteiros e decimais.
6*50 ⇒ res13: kotlin.Int = 300 6.0*50.0 ⇒ res14: kotlin.Double = 300.0 6.0*50 ⇒ res15: kotlin.Double = 300.0
- Chame alguns métodos em números. O Kotlin mantém os números como primitivos, mas permite chamar métodos neles como se fossem objetos.
2.times(3) ⇒ res5: kotlin.Int = 6 3.5.plus(4) ⇒ res8: kotlin.Double = 7.5 2.4.div(2) ⇒ res9: kotlin.Double = 1.2
Etapa 2: pratique o uso de tipos
O Kotlin não faz conversões implícitas entre tipos de números. Portanto, não é possível atribuir um valor short diretamente a uma variável long ou um Byte
a um Int
. Isso porque a conversão implícita de números é uma fonte comum de erros em programas. Você sempre pode atribuir valores de tipos diferentes usando a conversão.
- Para ver alguns dos casts possíveis, defina uma variável do tipo
Int
no REPL.
val i: Int = 6
- Crie uma variável e insira o nome dela mostrado acima, seguido por
.to
.
val b1 = i.to
O IntelliJ IDEA mostra uma lista de possíveis conclusões. O preenchimento automático funciona para variáveis e objetos de qualquer tipo.
- Selecione
toByte()
na lista e imprima a variável.
val b1 = i.toByte()
println(b1)
⇒ 6
- Atribua um valor
Byte
a variáveis de tipos diferentes.
val b2: Byte = 1 // OK, literals are checked statically
println(b2)
⇒ 1
val i1: Int = b2
⇒ error: type mismatch: inferred type is Byte but Int was expected
val i2: String = b2
⇒ error: type mismatch: inferred type is Byte but String was expected
val i3: Double = b2
⇒ error: type mismatch: inferred type is Byte but Double was expected
- Para as atribuições que retornaram erros, tente fazer a conversão.
val i4: Int = b2.toInt() // OK!
println(i4)
⇒ 1
val i5: String = b2.toString()
println(i5)
⇒ 1
val i6: Double = b2.toDouble()
println(i6)
⇒ 1.0
- Para tornar constantes numéricas longas mais legíveis, o Kotlin permite colocar sublinhados nos números, onde fizer sentido para você. Tente inserir constantes numéricas diferentes.
val oneMillion = 1_000_000 val socialSecurityNumber = 999_99_9999L val hexBytes = 0xFF_EC_DE_5E val bytes = 0b11010010_01101001_10010100_10010010
Etapa 3: aprenda o valor dos tipos de variáveis
O Kotlin é compatível com dois tipos de variáveis: alteráveis e inalteráveis. Com val
, você pode atribuir um valor por vez. Se você tentar atribuir algo novamente, receberá um erro. Com var
, você pode atribuir um valor e mudá-lo mais tarde no programa.
- Defina variáveis usando
val
evar
e atribua novos valores a elas.
var fish = 1
fish = 2
val aquarium = 1
aquarium = 2
⇒ error: val cannot be reassigned
É possível atribuir um valor a fish
e depois atribuir um novo valor, porque ele é definido com var
. Tentar atribuir um novo valor a aquarium
gera um erro porque ele é definido com val
.
O tipo armazenado em uma variável é inferido quando o compilador consegue descobrir pelo contexto. Se quiser, você sempre pode especificar o tipo de uma variável explicitamente usando a notação de dois pontos.
- Defina algumas variáveis e especifique o tipo explicitamente.
var fish: Int = 12
var lakes: Double = 2.5
Depois que um tipo é atribuído por você ou pelo compilador, não é possível mudá-lo. Caso contrário, um erro será gerado.
Etapa 4: saiba mais sobre strings
As strings em Kotlin funcionam praticamente como em qualquer outra linguagem de programação, usando "
para strings e '
para caracteres únicos. Além disso, é possível concatenar strings com o operador +
. É possível criar modelos de string combinando-os com valores. O nome $
variable
é substituído pelo texto que representa o valor. Isso é chamado de interpolação de variáveis.
- Crie um modelo de string.
val numberOfFish = 5
val numberOfPlants = 12
"I have $numberOfFish fish" + " and $numberOfPlants plants"
⇒ res20: kotlin.String = I have 5 fish and 12 plants
- Crie um modelo de string com uma expressão. Assim como em outras linguagens, o valor pode ser o resultado de uma expressão. Use chaves
{}
para definir a expressão.
"I have ${numberOfFish + numberOfPlants} fish and plants"
⇒ res21: kotlin.String = I have 17 fish and plants
Nesta tarefa, você vai aprender sobre booleanos e como verificar condições na linguagem de programação Kotlin. Assim como outras linguagens, o Kotlin tem booleanos e operadores booleanos, como menor que, igual a, maior que e assim por diante (<
, ==
, >
, !=
, <=
, >=
).
- Escreva uma instrução
if
/else
.
val numberOfFish = 50
val numberOfPlants = 23
if (numberOfFish > numberOfPlants) {
println("Good ratio!")
} else {
println("Unhealthy ratio")
}
⇒ Good ratio!
- Tente um intervalo em uma instrução
if
. Em Kotlin, a condição testada também pode usar intervalos.
val fish = 50
if (fish in 1..100) {
println(fish)
}
⇒ 50
- Escreva uma
if
com vários casos. Para condições mais complicadas, use&&
(e lógico) e||
(ou lógico). Assim como em outras linguagens, você pode ter vários casos usandoelse if
.
if (numberOfFish == 0) {
println("Empty tank")
} else if (numberOfFish < 40) {
println("Got fish!")
} else {
println("That's a lot of fish!")
}
⇒ That's a lot of fish!
- Teste uma instrução
when
. Há uma maneira melhor de escrever essa série de instruçõesif
/else if
/else
em Kotlin, usando a instruçãowhen
, que é como a instruçãoswitch
em outras linguagens. As condições em uma instruçãowhen
também podem usar intervalos.
when (numberOfFish) {
0 -> println("Empty tank")
in 1..39 -> println("Got fish!")
else -> println("That's a lot of fish!")
}
⇒ That's a lot of fish!
Nesta tarefa, você vai aprender sobre variáveis anuláveis e não anuláveis. Erros de programação envolvendo nulos são a origem de inúmeros bugs. O Kotlin busca reduzir bugs introduzindo variáveis não anuláveis.
Etapa 1: saiba mais sobre a capacidade de aceitar valores nulos
Por padrão, as variáveis não podem ser null
.
- Declare um
Int
e atribuanull
a ele.
var rocks: Int = null
⇒ error: null can not be a value of a non-null type Int
- Use o operador de ponto de interrogação,
?
, após o tipo para indicar que uma variável pode ser nula. Declare umInt?
e atribuanull
a ele.
var marbles: Int? = null
Quando você tem tipos de dados complexos, como uma lista:
- É possível permitir que os elementos da lista sejam nulos.
- Você pode permitir que a lista seja nula, mas, se não for, os elementos dela não poderão ser nulos.
- Você pode permitir que a lista ou os elementos sejam nulos.
As listas e alguns outros tipos de dados complexos serão abordados em uma tarefa posterior.
Etapa 2: saiba mais sobre o ? e operadores ?:
É possível testar null
com o operador ?
, evitando o trabalho de escrever muitas instruções if
/else
.
- Escreva um código mais longo para verificar se a variável
fishFoodTreats
não énull
. Em seguida, diminua essa variável.
var fishFoodTreats = 6
if (fishFoodTreats != null) {
fishFoodTreats = fishFoodTreats.dec()
}
- Agora, confira a maneira de escrever em Kotlin usando o operador
?
.
var fishFoodTreats = 6
fishFoodTreats = fishFoodTreats?.dec()
- Também é possível encadear testes nulos com o operador
?:
. Confira este exemplo:
fishFoodTreats = fishFoodTreats?.dec() ?: 0
É uma abreviação de "se fishFoodTreats
não for null
, diminua e use; caso contrário, use o valor após ?:
, que é 0". Se fishFoodTreats
for null
, a avaliação será interrompida, e o método dec()
não será chamado.
Um ponto sobre ponteiros nulos
Se você realmente gosta de NullPointerExceptions
, o Kotlin permite que você os mantenha. O operador de asserção não nula, !!
(duplo ponto de exclamação), converte qualquer valor para um tipo não nulo e gera uma exceção se o valor for null
.
val len = s!!.length // throws NullPointerException if s is null
Nesta tarefa, você vai aprender sobre matrizes e listas, além de diferentes maneiras de criar loops na linguagem de programação Kotlin.
Etapa 1: criar listas
As listas são um tipo fundamental no Kotlin e são semelhantes às listas em outras linguagens.
- Declare uma lista usando
listOf
e imprima-a. Não é possível mudar essa lista.
val school = listOf("mackerel", "trout", "halibut")
println(school)
⇒ [mackerel, trout, halibut]
- Declare uma lista que pode ser alterada usando
mutableListOf
. Remova um item.
val myList = mutableListOf("tuna", "salmon", "shark")
myList.remove("shark")
⇒ res36: kotlin.Boolean = true
O método remove()
retorna true
quando remove com sucesso o item transmitido.
Etapa 2: criar matrizes
Assim como outras linguagens, o Kotlin tem arrays. Ao contrário das listas em Kotlin, que têm versões mutáveis e imutáveis, não há uma versão mutável de um Array
. Depois de criar uma matriz, o tamanho dela é fixo. Não é possível adicionar ou remover elementos, exceto copiando para uma nova matriz.
As regras sobre o uso de val
e var
são as mesmas com matrizes e listas.
- Declare uma matriz de strings usando
arrayOf
. Use o utilitário de matrizjava.util.Arrays.toString()
para imprimir.
val school = arrayOf("shark", "salmon", "minnow")
println(java.util.Arrays.toString(school))
⇒ [shark, salmon, minnow]
- Uma matriz declarada com
arrayOf
não tem um tipo associado aos elementos, então é possível misturar tipos, o que é útil. Declare uma matriz com tipos diferentes.
val mix = arrayOf("fish", 2)
- Também é possível declarar matrizes com um tipo para todos os elementos. Declare uma matriz de números inteiros usando
intArrayOf()
. Há builders ou funções de instanciação correspondentes para matrizes de outros tipos.
val numbers = intArrayOf(1,2,3)
- Combine duas matrizes com o operador
+
.
val numbers = intArrayOf(1,2,3)
val numbers3 = intArrayOf(4,5,6)
val foo2 = numbers3 + numbers
println(foo2[5])
=> 3
- Teste diferentes combinações de matrizes e listas aninhadas. Assim como em outras linguagens, é possível aninhar matrizes e listas. Ou seja, quando você coloca uma matriz dentro de outra, tem uma matriz de matrizes, não uma matriz nivelada do conteúdo das duas. Os elementos de uma matriz também podem ser listas, e os elementos de listas podem ser matrizes.
val numbers = intArrayOf(1, 2, 3)
val oceans = listOf("Atlantic", "Pacific")
val oddList = listOf(numbers, oceans, "salmon")
println(oddList)
⇒ [[I@89178b4, [Atlantic, Pacific], salmon]
O primeiro elemento, numbers
, é um Array
. Quando você não usa a utilidade de matriz para imprimir, o Kotlin imprime o endereço em vez do conteúdo da matriz.
- Um recurso interessante do Kotlin é que você pode inicializar arrays com código em vez de inicializá-los como 0. Confira este exemplo:
val array = Array (5) { it * 2 }
println(java.util.Arrays.toString(array))
⇒ [0, 2, 4, 6, 8]
O código de inicialização está entre as chaves, {}
. No código, it
se refere ao índice da matriz, começando com 0.
Etapa 3: fazer loops
Agora que você tem listas e matrizes, o loop pelos elementos funciona como esperado.
- Crie uma matriz. Use uma repetição
for
para iterar a matriz e imprimir os elementos.
val school = arrayOf("shark", "salmon", "minnow")
for (element in school) {
print(element + " ")
}
⇒ shark salmon minnow
- Em Kotlin, é possível fazer um loop pelos elementos e pelos índices ao mesmo tempo. Confira este exemplo:
for ((index, element) in school.withIndex()) {
println("Item at $index is $element\n")
}
⇒ Item at 0 is shark Item at 1 is salmon Item at 2 is minnow
- Tente usar diferentes tamanhos e intervalos de etapas. É possível especificar intervalos de números ou caracteres em ordem alfabética. E, como em outras linguagens, você não precisa avançar em 1. Você pode voltar usando
downTo
.
for (i in 1..5) print(i)
⇒ 12345
for (i in 5 downTo 1) print(i)
⇒ 54321
for (i in 3..6 step 2) print(i)
⇒ 35
for (i in 'd'..'g') print (i)
⇒ defg
- Teste alguns loops. Assim como outras linguagens, o Kotlin tem loops
while
edo...while
, além de operadores++
e--
. O Kotlin também tem loopsrepeat
.
var bubbles = 0
while (bubbles < 50) {
bubbles++
}
println("$bubbles bubbles in the water\n")
do {
bubbles--
} while (bubbles > 50)
println("$bubbles bubbles in the water\n")
repeat(2) {
println("A fish is swimming")
}
⇒ 50 bubbles in the water 49 bubbles in the water A fish is swimmingA fish is swimming
O Kotlin é muito semelhante a outras linguagens quando se trata de conceitos básicos, como operadores, listas e loops, mas há algumas diferenças importantes.
Os seguintes recursos podem ser diferentes no Kotlin em comparação com outras linguagens:
- Os tipos do Kotlin não podem ser convertidos implicitamente. Use a conversão de tipo.
- As variáveis declaradas com
val
só podem ser atribuídas uma vez. - Por padrão, as variáveis do Kotlin não aceitam valores nulos. Use
?
para tornar as variáveis anuláveis. - Com Kotlin, é possível percorrer o índice e os elementos de uma matriz ao mesmo tempo em um loop
for
.
As seguintes construções de programação em Kotlin são semelhantes às de outras linguagens:
- Matrizes e listas podem ter um único tipo ou tipos mistos.
- Matrizes e listas podem ser aninhadas.
- É possível criar loops com
for
,while
,do
/while
erepeat
. - A instrução
when
é a versão do Kotlin da instruçãoswitch
, maswhen
é mais flexível.
Documentação do Kotlin
Se você quiser mais informações sobre algum tópico deste curso ou se tiver dúvidas, https://kotlinlang.org é o melhor ponto de partida.
- Conversão explícita de tipo
- Como definir variáveis (link em inglês)
- Modelos de string (link em inglês)
- Valores anuláveis
- Listas
- Matrizes
if
,when
,for
,while
- Operador
?:
(Elvis) - operador
!!
Tutoriais do Kotlin
O site https://try.kotlinlang.org inclui tutoriais avançados chamados Kotlin Koans, um interpretador baseado na Web e um conjunto completo de documentação de referência com exemplos.
Curso Udacity
Para conferir o curso da Udacity sobre esse tema, consulte Treinamento do Kotlin para programadores (link em inglês).
IntelliJ IDEA
A documentação do IntelliJ IDEA está disponível no site da JetBrains.
Esta seção lista as possíveis atividades de dever de casa para os alunos que estão fazendo este codelab como parte de um curso ministrado por um professor. Cabe ao professor fazer o seguinte:
- Atribuir o dever de casa, se necessário.
- Informar aos alunos como enviar deveres de casa.
- Atribuir nota aos deveres de casa.
Os professores podem usar essas sugestões o quanto quiserem, podendo passar os exercícios que acharem mais apropriados como dever de casa.
Se você estiver seguindo este codelab por conta própria, sinta-se à vontade para usar esses deveres de casa para testar seu conhecimento.
Responda estas perguntas
Pergunta 1
Qual das opções a seguir declara uma lista imutável de strings?
▢ val school = arrayOf("shark", "salmon", "minnow")
▢ var school = arrayOf("shark", "salmon", "minnow")
▢ val school = listOf("shark", "salmon", "minnow")
▢ val school = mutableListOf("shark", "salmon", "minnow")
Pergunta 2
Qual será a saída do seguinte código?for (i in 3..8 step 2) print(i)
▢ 345678
▢ 468
▢ 38
▢ 357
Pergunta 3
Qual é a finalidade do ponto de interrogação neste código?var rocks: Int? = 3
▢ O tipo da variável rocks
não está fixo.
▢ A variável rocks
pode ser definida como nula.
▢ A variável rocks
não pode ser definida como nula.
▢ A variável rocks
não deve ser inicializada imediatamente.
Siga para a próxima lição:
Para ter uma visão geral do curso, incluindo links para outros codelabs, consulte "Treinamento do Kotlin para programadores: seja bem-vindo ao curso".