Treinamento do Kotlin para programadores 3: funções

Este codelab faz parte do curso Treinamento do Kotlin para programadores. Você aproveitará mais o 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ê criará um programa Kotlin e aprenderá sobre funções no Kotlin, incluindo valores padrão para parâmetros, filtros, lambdas e funções compactas.

Em vez de criar um único app de exemplo, as lições deste curso foram desenvolvidas para aumentar seu conhecimento, mas são semi-independentes umas das outras para que você possa ler as seções que já conhece. Para conectá-los, muitos dos exemplos usam um tema de aquário. Se você quiser ver a história completa do aquário, confira o curso Bootcamp de Kotlin para programadores na Udacity.

O que você já precisa saber

  • os conceitos básicos de uma linguagem de programação moderna, orientada por objetos e estática
  • Como programar com classes, métodos e gerenciamento de exceções em pelo menos um idioma.
  • Como trabalhar com REPL (Read-Eval-Print Loop) do Kotlin no IntelliJ IDEA
  • os conceitos básicos do Kotlin, incluindo tipos, operadores e loops;

Este codelab é destinado a programadores que conhecem uma linguagem orientada a objetos e querem saber mais sobre Kotlin.

O que você vai aprender

  • Como criar um programa com uma função main() e argumentos no IntelliJ IDEA
  • Como usar valores padrão e funções compactas
  • Como aplicar filtros a listas
  • Como criar lambdas básicos e funções de ordem superior.

Atividades do laboratório

  • Trabalhe com o REPL para testar um código.
  • Trabalhe com o IntelliJ IDEA para criar programas básicos em Kotlin.

Nesta tarefa, você criará um programa em Kotlin e aprenderá sobre a função main() e como transmitir argumentos para um programa usando a linha de comando.

Talvez você se lembre da função printHello() que você inseriu no REPL em um codelab anterior:

fun printHello() {
    println ("Hello World")
}

printHello()
⇒ Hello World

Para definir funções, use a palavra-chave fun, seguida do nome da função. Assim como em outras linguagens de programação, os parênteses () são para argumentos de função, se houver. As chaves {} enquadram o código da função. Não há tipo de retorno para essa função, porque ela não retorna nada.

Etapa 1: criar um arquivo Kotlin

  1. Abra o IntelliJ IDEA.
  2. O painel Project à esquerda no IntelliJ IDEA mostra uma lista de pastas e arquivos do projeto. Encontre e clique com o botão direito do mouse na pasta src em Hello Kotlin. Você já deve ter o projeto Hello Kotlin do codelab anterior.
  3. Selecione New > Kotlin File / Class.
  4. Mantenha Kind como File e nomeie o arquivo como Hello.
  5. Clique em OK.

Agora há um arquivo na pasta src chamado Hello.kt.

Etapa 2: adicionar o código e executar o programa

  1. Assim como em outras linguagens, a função main() do Kotlin especifica o ponto de entrada para execução. Todos os argumentos de linha de comando são transmitidos como uma matriz de strings.

    Digite ou cole o seguinte código no arquivo Hello.kt:
fun main(args: Array<String>) {
    println("Hello, world!")
}

Assim como a função printHello() anterior, ela não tem uma instrução return. Cada função no Kotlin retorna algo, mesmo quando nada é especificado explicitamente. Portanto, uma função como essa função main() retorna um tipo kotlin.Unit, que é uma maneira de não informar nenhum valor para o Kotlin.

  1. Para executar o programa, clique no triângulo verde à esquerda da função main(). Selecione Run 'HelloKt' no menu.
  2. O IntelliJ IDEA compila e executa o programa. Os resultados aparecem em um painel de registro na parte inferior, como mostrado abaixo.

Etapa 3: transmitir argumentos para main()

Como você está executando seu programa pelo IntelliJ IDEA e não pela linha de comando, é necessário especificar os argumentos do programa de maneira um pouco diferente.

  1. Selecione Run > Edit Configurations. A janela Run/Debug Configurations será aberta.
  2. Digite Kotlin! no campo Argumentos do programa.
  3. Clique em OK.

Etapa 4: alterar o código para usar um modelo de string

Um modelo de string insere uma variável ou expressão em uma string, e $ especifica que parte dela será uma variável ou expressão. As chaves {} enquadram a expressão, se houver.

  1. Em Hello.kt, altere a mensagem de saudação para usar o primeiro argumento transmitido ao programa, args[0], em vez de "world".
fun main(args: Array<String>) {
    println("Hello, ${args[0]}")
}
  1. Execute o programa. A saída incluirá o argumento especificado.
⇒ Hello, Kotlin!

Nesta tarefa, você aprenderá por que quase tudo no Kotlin tem um valor e por que isso é útil.

Algumas outras linguagens têm instruções, que são linhas de código sem valor. No Kotlin, quase tudo é uma expressão e tem um valor, mesmo que seja kotlin.Unit.

  1. No Hello.kt, escreva o código em main() para atribuir uma println() a uma variável com o nome isUnit e imprimi-la. println() não retorna um valor e retorna kotlin.Unit.
// Will assign kotlin.Unit
val isUnit = println("This is an expression")
println(isUnit)
  1. Execute o programa. O primeiro println() exibe a string "This is an expression". A segunda println() exibe o valor da primeira instrução println(), ou seja, kotlin.Unit.
⇒ This is an expression
kotlin.Unit
  1. Declare um val chamado temperature e inicialize-o como 10.
  2. Declare outro val chamado isHot e atribua o valor de retorno de uma instrução if/else a isHot, conforme mostrado no código a seguir. Como é uma expressão, é possível usar o valor da expressão if imediatamente.
val temperature = 10
val isHot = if (temperature > 50) true else false
println(isHot)
⇒ false
  1. Usar o valor de uma expressão em um modelo de string. Adicione código para verificar a temperatura e determinar se o peixe é seguro ou muito quente. Em seguida, execute o programa.
val temperature = 10
val message = "The water temperature is ${ if (temperature > 50) "too warm" else "OK" }."
println(message)
⇒ The water temperature is OK.

Nesta tarefa, você aprenderá mais sobre as funções no Kotlin e sobre a expressão condicional when, que é muito útil.

Etapa 1: criar algumas funções

Nesta etapa, você reúne tudo o que aprendeu e criou funções com diferentes tipos. Você pode substituir o conteúdo de Hello.kt por este novo código.

  1. Escreva uma função com o nome feedTheFish() que chama randomDay() para receber um dia aleatório da semana. Use um modelo de string para exibir um food para o peixe durante o dia. Por enquanto, os peixes comem a mesma comida todos os dias.
fun feedTheFish() {
    val day = randomDay()
    val food = "pellets"
    println ("Today is $day and the fish eat $food")
}

fun main(args: Array<String>) {
    feedTheFish()
}
  1. Escreva a função randomDay() para escolher um dia aleatório em uma matriz e retorná-la.

A função nextInt() usa um limite de números inteiros, o que limita o número de Random() a 0 a 6 para corresponder à matriz week.

fun randomDay() : String {
    val week = arrayOf ("Monday", "Tuesday", "Wednesday", "Thursday",
            "Friday", "Saturday", "Sunday")
    return week[Random().nextInt(week.size)]
}
  1. As funções Random() e nextInt() são definidas em java.util.*. Na parte superior do arquivo, adicione a importação necessária:
import java.util.*    // required import
  1. Execute o programa e verifique a saída.
⇒ Today is Tuesday and the fish eat pellets

Etapa 2: usar uma expressão "when"

Estendendo-se ainda mais, mude o código para escolher diferentes alimentos para dias diferentes usando uma expressão when. A instrução when é semelhante a switch em outras linguagens de programação, mas a when é interrompida automaticamente no fim de cada ramificação. Isso também garante que o código cubra todas as ramificações se você estiver verificando uma enumeração.

  1. Em Hello.kt, adicione uma função chamada fishFood(), que aceita um dia como String e retorna o alimento dos peixes do dia como String. Use when() para que cada dia o peixe receba um alimento específico. Execute o programa algumas vezes para ver saídas diferentes.
fun fishFood (day : String) : String {
    var food = ""
    when (day) {
        "Monday" -> food = "flakes"
        "Tuesday" -> food = "pellets"
        "Wednesday" -> food = "redworms"
        "Thursday" -> food = "granules"
        "Friday" -> food = "mosquitoes"
        "Saturday" -> food = "lettuce"
        "Sunday" -> food = "plankton"
    }
    return food
}

fun feedTheFish() {
    val day = randomDay()
    val food = fishFood(day)

    println ("Today is $day and the fish eat $food")
}
⇒ Today is Thursday and the fish eat granules
  1. Adicione uma ramificação padrão à expressão when usando else. Para testar, para garantir que o padrão seja usado algumas vezes no programa, remova as ramificações Tuesday e Saturday.

    Ter uma ramificação padrão garante que food receba um valor antes de ser retornado, para que ele não precise mais ser inicializado. Como o código agora atribui uma string a food apenas uma vez, você pode declarar food com val em vez de var.
fun fishFood (day : String) : String {
    val food : String
    when (day) {
        "Monday" -> food = "flakes"
        "Wednesday" -> food = "redworms"
        "Thursday" -> food = "granules"
        "Friday" -> food = "mosquitoes"
        "Sunday" -> food = "plankton"
        else -> food = "nothing"
    }
    return food
}
  1. Como cada expressão tem um valor, você pode tornar esse código um pouco mais conciso. Retorne o valor da expressão when diretamente e elimine a variável food. O valor da expressão when é o valor da última expressão da ramificação que satisfez a condição.
fun fishFood (day : String) : String {
    return when (day) {
        "Monday" -> "flakes"
        "Wednesday" -> "redworms"
        "Thursday" -> "granules"
        "Friday" -> "mosquitoes"
        "Sunday" -> "plankton"
        else -> "nothing"
    }
}

A versão final do seu programa é semelhante ao código abaixo.

import java.util.*    // required import

fun randomDay() : String {
    val week = arrayOf ("Monday", "Tuesday", "Wednesday", "Thursday",
        "Friday", "Saturday", "Sunday")
    return week[Random().nextInt(week.size)]
}

fun fishFood (day : String) : String {
    return when (day) {
        "Monday" -> "flakes"
        "Wednesday" -> "redworms"
        "Thursday" -> "granules"
        "Friday" -> "mosquitoes"
        "Sunday" -> "plankton"
        else -> "nothing"
    }
}

fun feedTheFish() {
    val day = randomDay()
    val food = fishFood(day)
    println ("Today is $day and the fish eat $food")
}

fun main(args: Array<String>) {
    feedTheFish()
}

Nesta tarefa, você aprenderá sobre os valores padrão de funções e métodos. Você também aprenderá sobre funções compactas, que podem tornar seu código mais conciso e legível e reduzir o número de caminhos de código para testes. As funções compactas também são chamadas de funções de expressão única.

Etapa 1: criar um valor padrão para um parâmetro

No Kotlin, você pode transmitir argumentos por nome de parâmetro. Também é possível especificar valores padrão para parâmetros. Se um argumento não for fornecido pelo autor da chamada, o valor padrão será usado. Posteriormente, ao gravar métodos (funções de membro), você pode evitar a criação de muitas versões sobrecarregadas do mesmo método.

  1. No Hello.kt, escreva uma função swim() com um parâmetro String chamado speed, que exibe a velocidade dos peixes. O parâmetro speed tem um valor padrão de "fast".
fun swim(speed: String = "fast") {
   println("swimming $speed")
}
  1. Na função main(), chame a função swim() de três maneiras. Primeiro, chame a função usando o padrão. Em seguida, chame a função e transmita o parâmetro speed sem um nome e, em seguida, chame a função nomeando o parâmetro speed.
swim()   // uses default speed
swim("slow")   // positional argument
swim(speed="turtle-like")   // named parameter
⇒ swimming fast
swimming slow
swimming turtle-like

Etapa 2: adicionar os parâmetros necessários

Se nenhum padrão for especificado para um parâmetro, o argumento correspondente sempre precisará ser passado.

  1. No Hello.kt, escreva uma função shouldChangeWater() que usa três parâmetros: day, temperature e um nível dirty. A função retorna true quando a água precisa ser alterada. Isso acontece no domingo, se a temperatura for muito alta ou se a água estiver muito suja. O dia da semana é obrigatório, mas a temperatura padrão é 22, e o nível de sujeira padrão é 20.

    Use uma expressão when sem um argumento, o que no Kotlin funciona como uma série de verificações if/else if.
fun shouldChangeWater (day: String, temperature: Int = 22, dirty: Int = 20): Boolean {
    return when {
        temperature > 30 -> true
        dirty > 30 -> true
        day == "Sunday" ->  true
        else -> false
    }
}
  1. Chame shouldChangeWater() de feedTheFish() e informe o dia. O parâmetro day não tem um padrão, então você precisa especificar um argumento. Os outros dois parâmetros de shouldChangeWater() têm valores padrão, então você não precisa transmitir argumentos para eles.
fun feedTheFish() {
    val day = randomDay()
    val food = fishFood(day)
    println ("Today is $day and the fish eat $food")
    println("Change water: ${shouldChangeWater(day)}")
}
=> Today is Thursday and the fish eat granules
Change water: false

Etapa 3: criar funções compactas

A expressão when que você escreveu na etapa anterior agrupa muita lógica em uma pequena quantidade de código. Se quiser descompactá-la um pouco ou se as condições a serem verificadas forem mais complicadas, você poderá usar algumas variáveis locais bem nomeadas. Mas a maneira Kotlin de fazer isso é com funções compactas.

Funções compactas, ou funções de expressão única, são um padrão comum no Kotlin. Quando uma função retorna os resultados de uma única expressão, você pode especificar o corpo da função após um símbolo =, omitir as chaves {} e omitir a return.

  1. em Hello.kt, adicione funções compactas para testar as condições.
fun isTooHot(temperature: Int) = temperature > 30

fun isDirty(dirty: Int) = dirty > 30

fun isSunday(day: String) = day == "Sunday"
  1. Mude shouldChangeWater() para chamar as novas funções.
fun shouldChangeWater (day: String, temperature: Int = 22, dirty: Int = 20): Boolean {
    return when {
        isTooHot(temperature) -> true
        isDirty(dirty) -> true
        isSunday(day) -> true
        else  -> false
    }
}
  1. Execute o programa. A saída do println() com shouldChangeWater() será a mesma de antes de usar funções compactas.

Valores padrão

O valor padrão de um parâmetro não precisa ser um valor. Ele pode ser outra função, conforme mostrado no exemplo parcial a seguir:

fun shouldChangeWater (day: String, temperature: Int = 22, dirty: Int = getDirtySensorReading()): Boolean {
    ...

Nesta tarefa, você aprenderá um pouco sobre filtros em Kotlin. Os filtros são uma forma prática de fazer parte de uma lista com base em alguma condição.

Etapa 1: criar um filtro

  1. Em Hello.kt, defina uma lista de decorações de aquário no nível superior com listOf(). Você pode substituir o conteúdo do Hello.kt.
val decorations = listOf ("rock", "pagoda", "plastic plant", "alligator", "flowerpot")
  1. Crie uma nova função main() com uma linha para exibir apenas as decorações que começam com a letra 'p'. O código da condição de filtro está entre chaves {}, e it refere-se a cada item conforme o filtro se repete. Se a expressão retornar true, o item será incluído.
fun main() {
    println( decorations.filter {it[0] == 'p'})
}
  1. Execute o programa. Você verá a seguinte saída na janela Run:
⇒ [pagoda, plastic plant]

Etapa 2: comparar filtros rápidos e lentos

Se você conhece filtros em outras linguagens, talvez se pergunte se os filtros em Kotlin são ávidos ou lentos. A lista de resultados é criada imediatamente ou quando a lista é acessada? Em Kotlin, isso acontece do jeito que você precisar. Por padrão, a filter está pronta e, sempre que você usa o filtro, uma lista é criada.

Para tornar o filtro lento, você pode usar um Sequence, uma coleção que só pode analisar um item por vez, começando pelo início e indo até o fim. Essa é exatamente a API necessária para um filtro lento.

  1. Em Hello.kt, mude seu código para atribuir a lista filtrada a uma variável com o nome eager e imprima-a.
fun main() {
    val decorations = listOf ("rock", "pagoda", "plastic plant", "alligator", "flowerpot")

    // eager, creates a new list
    val eager = decorations.filter { it [0] == 'p' }
    println("eager: " + eager)
  1. Abaixo do código, avalie o filtro usando um Sequence com asSequence(). Atribua a sequência a uma variável chamada filtered e exiba-a.
   // lazy, will wait until asked to evaluate
    val filtered = decorations.asSequence().filter { it[0] == 'p' }
    println("filtered: " + filtered)

Quando você retorna os resultados do filtro como uma Sequence, a variável filtered não terá uma nova lista. Ela terá um Sequence dos elementos da lista e do conhecimento do filtro a ser aplicado a esses elementos. Sempre que você acessar elementos da Sequence, o filtro será aplicado e o resultado será retornado para você.

  1. Force a avaliação da sequência convertendo-a em um List com toList(). Exiba o resultado.
    // force evaluation of the lazy list
    val newList = filtered.toList()
    println("new list: " + newList)
  1. Execute o programa e observe o resultado.
⇒ eager: [pagoda, plastic plant]
filtered: kotlin.sequences.FilteringSequence@386cc1c4
new list: [pagoda, plastic plant]

Para visualizar o que está acontecendo com a Sequence e a avaliação lenta, use a função map(). A função map() executa uma transformação simples em cada elemento da sequência.

  1. Com a mesma lista de decorations acima, faça uma transformação com map() que não faz nada e simplesmente retorna o elemento que foi transmitido. Adicione uma println() para mostrar cada vez que um elemento for acessado e atribua a sequência a uma variável com o nome lazyMap.
    val lazyMap = decorations.asSequence().map {
        println("access: $it")
        it
    }
  1. Exiba o lazyMap, exiba o primeiro elemento da lazyMap usando first() e exiba o lazyMap convertido em um List.
    println("lazy: $lazyMap")
    println("-----")
    println("first: ${lazyMap.first()}")
    println("-----")
    println("all: ${lazyMap.toList()}")
  1. Execute o programa e observe o resultado. Imprimir lazyMap apenas exibe uma referência à Sequence. A println() interna não é chamada. A impressão do primeiro elemento acessa apenas o primeiro. A conversão do Sequence em um List acessa todos os elementos.
⇒ lazy: kotlin.sequences.TransformingSequence@5ba23b66
-----
access: rock
first: rock
-----
access: rock
access: pagoda
access: plastic plant
access: alligator
access: flowerpot
all: [rock, pagoda, plastic plant, alligator, flowerpot]
  1. Crie uma nova Sequence usando o filtro original antes de aplicar map. Exiba o resultado.
    val lazyMap2 = decorations.asSequence().filter {it[0] == 'p'}.map {
        println("access: $it")
        it
    }
    println("-----")
    println("filtered: ${ lazyMap2.toList() }")
  1. Execute o programa e observe a saída adicional. Assim como para receber o primeiro elemento, o println() interno é chamado apenas para os elementos que são acessados.
⇒
-----
access: pagoda
access: plastic plant
filtered: [pagoda, plastic plant]

Nesta tarefa, você verá uma introdução aos lambdas e às funções de ordem superior (link em inglês) no Kotlin.

Lambdas

Além das funções nomeadas tradicionais, o Kotlin é compatível com lambdas. Uma lambda é uma expressão que faz uma função. Mas, em vez de declarar uma função nomeada, você declara uma função sem nome. Parte do que torna isso útil é que a expressão lambda agora pode ser transmitida como dados. Em outras linguagens, os lambdas são chamados de funções anônimas, literais de função ou nomes semelhantes.

Funções de ordem superior

É possível criar uma função de ordem superior transmitindo uma lambda para outra função. Na tarefa anterior, você criou uma função de ordem superior chamada filter. Você transmitiu a seguinte expressão lambda para filter como a condição a ser verificada:
{it[0] == 'p'}

Da mesma forma, map é uma função de ordem superior, e o lambda transmitido a ela era a transformação a ser aplicada.

Etapa 1: saber mais sobre lambdas

  1. Assim como as funções nomeadas, lambdas podem ter parâmetros. Para lambdas, os parâmetros (e seus tipos, se necessário) ficam à esquerda do que é chamado de seta de função ->. O código a ser executado vai para a direita da seta de função. Depois que o lambda for atribuído a uma variável, você poderá chamá-lo como uma função.

    Usando o REPL (Tools > Kotlin > Kotlin REPL), teste este código:
var dirtyLevel = 20
val waterFilter = { dirty : Int -> dirty / 2}
println(waterFilter(dirtyLevel))
⇒ 10

Nesse exemplo, o lambda usa um Int com o nome dirty e retorna dirty / 2. Porque a filtragem remove a sujeira.

  1. A sintaxe do Kotlin para tipos de função está intimamente relacionada à sintaxe do lambdas. Use esta sintaxe para declarar claramente uma variável que contém uma função:
val waterFilter: (Int) -> Int = { dirty -> dirty / 2 }

Veja o que o código diz:

  • Crie uma variável com o nome waterFilter.
  • waterFilter pode ser qualquer função que use um Int e retorne um Int.
  • Atribua um lambda a waterFilter.
  • A lambda retorna o valor do argumento dirty dividido por 2.

Não é mais necessário especificar o tipo do argumento lambda. O tipo é calculado por inferência de tipo.

Etapa 2: criar uma função de ordem superior

Até o momento, os exemplos de lambdas se parecem principalmente com funções. O verdadeiro poder dos lambdas é usá-los para criar funções de ordem superior, em que o argumento para uma função é outra.

  1. Escreva uma função de ordem superior. Este é um exemplo básico, uma função que usa dois argumentos. O primeiro argumento é um número inteiro. O segundo argumento é uma função que aceita um número inteiro e retorna um número inteiro. Experimente no REPL.
fun updateDirty(dirty: Int, operation: (Int) -> Int): Int {
   return operation(dirty)
}

O corpo do código chama a função que foi transmitida como o segundo argumento e transmite o primeiro argumento para ele.

  1. Para chamá-la, transmita um número inteiro e uma função a ela.
val waterFilter: (Int) -> Int = { dirty -> dirty / 2 }
println(updateDirty(30, waterFilter))
⇒ 15

A função que você transmite não precisa ser um lambda. Ela pode ser uma função nomeada normal. Para especificar o argumento como uma função regular, use o operador ::. Dessa forma, o Kotlin saberá que você está transmitindo a referência da função como um argumento, não tentando chamar a função.

  1. Tente transmitir uma função nomeada normal para updateDirty().
fun increaseDirty( start: Int ) = start + 1

println(updateDirty(15, ::increaseDirty))
⇒ 16
var dirtyLevel = 19;
dirtyLevel = updateDirty(dirtyLevel) { dirtyLevel -> dirtyLevel + 23}
println(dirtyLevel)
⇒ 42
  • Para criar um arquivo de origem Kotlin no IntelliJ IDEA, comece com um projeto Kotlin.
  • Para compilar e executar um programa no IntelliJ IDEA, clique no triângulo verde ao lado da função main(). O resultado será exibido em uma janela de registro abaixo.
  • No IntelliJ IDEA, especifique argumentos de linha de comando para transmitir à função main() em Run > Edit Configurations.
  • Quase tudo no Kotlin tem um valor. Você pode usar esse fato para tornar o código mais conciso usando o valor de if ou when como uma expressão ou um valor de retorno.
  • Os argumentos padrão removem a necessidade de várias versões de uma função ou método. Exemplo:
    fun swim(speed: String = "fast") { ... }
  • Funções compactas, ou funções de expressão única, podem tornar o código mais legível. Exemplo:
    fun isTooHot(temperature: Int) = temperature > 30
  • Você aprendeu algumas noções básicas sobre filtros, que usam expressões lambda. Exemplo:
    val beginsWithP = decorations.filter { it [0] == 'p' }
  • Uma expressão lambda é uma expressão que faz uma função sem nome. As expressões lambda são definidas entre as chaves {}.
  • Em uma função de ordem superior, você transmite uma função, como uma expressão lambda, para outra função como dados. Exemplo:
    dirtyLevel = updateDirty(dirtyLevel) { dirtyLevel -> dirtyLevel + 23}

Há muita coisa nesta lição, principalmente se você não conhece muito sobre lambdas. Uma lição posterior aborda novamente os lambdas e as funções de ordem superior.

Documentação do Kotlin

Se quiser mais informações sobre qualquer assunto deste curso ou se tiver dificuldades, https://kotlinlang.org é seu melhor ponto de partida.

Tutoriais do Kotlin

O site https://try.kotlinlang.org (link em inglês) tem tutoriais elaborados chamados Kotlin Koans, um intérprete baseado na Web, e um conjunto completo de documentação de referência com exemplos.

Curso Udacity

Para ver o curso da Udacity sobre esse assunto, consulte Bootcamp de Kotlin para programadores (link em inglês).

IntelliJ IDEA

A documentação do IntelliJ IDEA (em inglês) pode ser encontrada no site da JetBrains.

Esta seção lista as possíveis atividades para os alunos que estão trabalhando neste codelab como parte de um curso ministrado por um instrutor. Cabe ao instrutor fazer o seguinte:

  • Se necessário, atribua o dever de casa.
  • Informe aos alunos como enviar o dever de casa.
  • Atribua nota aos trabalhos de casa.

Os professores podem usar essas sugestões o quanto quiserem, e eles devem se sentir à vontade para passar o dever de casa como achar adequado.

Se você estiver fazendo este codelab por conta própria, use essas atividades para testar seu conhecimento.

Responda a estas perguntas

Pergunta 1

A função contains(element: String) retornará true se a string element estiver contida na string em que ela é chamada. Qual será a saída do código a seguir?

val decorations = listOf ("rock", "pagoda", "plastic plant", "alligator", "flowerpot")

println(decorations.filter {it.contains('p')})

[pagoda, plastic, plant]

[pagoda, plastic plant]

[pagoda, plastic plant, flowerpot]

[rock, alligator]

Pergunta 2

Na definição da função a seguir, qual dos parâmetros é obrigatório?
fun shouldChangeWater (day: String, temperature: Int = 22, dirty: Int = 20, numDecorations: Int = 0): Boolean {...}

numDecorations

dirty

day

temperature

Pergunta 3

Você pode transmitir uma função nomeada normal (não o resultado da chamada) para outra função. Como você transmitiria increaseDirty( start: Int ) = start + 1 para updateDirty(dirty: Int, operation: (Int) -> Int)?

updateDirty(15, &increaseDirty())

updateDirty(15, increaseDirty())

updateDirty(15, ("increaseDirty()"))

updateDirty(15, ::increaseDirty)

Vá para a próxima lição: 4. Classes e objetos

Para ter uma visão geral do curso, incluindo links para outros codelabs, consulte "Bootcamp de Kotlin para programadores: bem-vindo ao curso."