Escrever condicionais em Kotlin

1. Antes de começar

Condicionais são uma das bases mais importantes da programação. Eles são comandos em linguagens de programação que processam decisões. Com os condicionais, o código é dinâmico, o que significa que ele pode se comportar de maneira diferente dependendo da condição.

Este codelab ensina a usar instruções e expressões if/else e when para criar condicionais em Kotlin.

Pré-requisitos

  • Conhecimentos básicos de programação em Kotlin, incluindo variáveis e as funções println() e main().

O que você vai aprender

  • Como escrever expressões booleanas.
  • Como escrever instruções if/else.
  • Como escrever instruções when.
  • Como escrever expressões if/else.
  • Como escrever expressões when.
  • Como usar vírgulas para definir o comportamento comum de várias ramificações em condicionais when.
  • Como usar o intervalo in para definir um comportamento comum para um intervalo de ramificações em condicionais when.
  • Como usar a palavra-chave is para escrever instruções condicionais when.

O que é necessário

  • Um navegador da Web com acesso ao Playground Kotlin.

2. Usar instruções if/else para expressar condições

Na vida real, é comum fazer as coisas de maneira diferente com base na situação que você enfrenta. Por exemplo, quando está frio, você usa uma jaqueta. Quando está quente, você não usa.

Um fluxograma que descreve uma decisão tomada quando o clima está frio. Uma seta sim aponta para

A tomada de decisões também é um conceito fundamental na programação. Você escreve instruções sobre como um programa deve se comportar em determinada situação para agir ou reagir conforme necessário quando a situação ocorrer. Em Kotlin, quando quiser que o programa execute diferentes ações com base em uma condição, você pode usar uma instrução if/else. Na próxima seção, você vai escrever uma instrução if.

Escrever condições if com expressões booleanas

Imagine que você quer criar um programa que informe aos motoristas o que eles devem fazer quando estiverem em um semáforo. Foque na primeira condição: um semáforo vermelho. O que você faz em um semáforo vermelho? Para o veículo.

Um fluxograma que descreve uma decisão tomada quando a cor do semáforo é vermelha. Uma seta sim aponta para um

Em Kotlin, você pode expressar essa condição com uma instrução if. Veja a anatomia de uma instrução if:

Um diagrama que descreve uma instrução "if" com a palavra-chave "if" seguida por parênteses com uma condição dentro dela. Depois da condição, há um par de chaves com um corpo. O bloco da condição está destacado.

Nas instruções if, use a palavra-chave if seguida pela condição que você quer avaliar. Você precisa expressar a condição com uma expressão booleana. As expressões combinam valores, variáveis e operadores que retornam um valor. As expressões booleanas retornam um valor booleano.

Anteriormente, você aprendeu sobre os operadores de atribuição. Por exemplo:

val number = 1

O operador de atribuição = atribui um valor 1 à variável number.

Por outro lado, as expressões booleanas são construídas com operadores de comparação, que comparam valores ou variáveis nos dois lados da equação. Veja um operador de comparação.

1 == 1

O operador de comparação == compara os valores entre si. Qual valor booleano você acha que essa expressão retorna?

Encontre o valor booleano desta expressão:

  1. Use o Playground Kotlin para executar seu código.
  2. No corpo da função, adicione uma função println() e, em seguida, transmita a expressão 1 == 1 como um argumento:
fun main() {
    println(1 == 1)
}
  1. Execute o programa e veja o resultado:
true

O primeiro valor de 1 é igual ao segundo valor de 1. Portanto, a expressão booleana retorna um valor booleano true.

Testar

Além do operador ==, há outros operadores de comparação que podem ser usados para criar expressões booleanas:

  • Menor que: <
  • Maior que: >
  • Menor ou igual a: <=
  • Maior ou igual a: >=
  • Diferente de: !=

Pratique o uso de operadores de comparação com expressões simples:

  1. No argumento, substitua o operador de comparação == pelo operador <:
fun main() {
    println(1 < 1)
}
  1. Execute o programa e veja o resultado:

O resultado retorna um valor false porque o primeiro valor de 1 não é menor que o segundo valor de 1.

false
  1. Repita as duas primeiras etapas com os outros operadores de comparação e números.

Escrever uma instrução if simples

Agora que você viu alguns exemplos de como escrever expressões booleanas, já pode escrever sua primeira instrução if. A sintaxe de uma instrução if é esta:

Um diagrama que descreve uma instrução &quot;if&quot; com a palavra-chave &quot;if&quot; seguida por parênteses com uma condição dentro dela. Depois da condição, há um par de chaves com um corpo. O bloco do corpo está destacado.

Uma instrução if começa com a palavra-chave if seguida por uma condição, que é uma expressão booleana entre parênteses e um conjunto de chaves. O corpo é uma série de instruções ou expressões que são colocadas dentro de um par de chaves depois da condição. Essas instruções ou expressões são executadas somente quando a condição é atendida. Em outras palavras, as instruções dentro das chaves só são executadas quando uma expressão booleana na ramificação if retorna um valor true.

Escreva uma instrução if para a condição de semáforo vermelho:

  1. Na função main(), crie uma variável trafficLightColor e atribua a ela um valor "Red":
fun main() {
    val trafficLightColor = "Red"
}
  1. Adicione uma instrução if para a condição de semáforo vermelho e transmita a ela uma expressão trafficLightColor == "Red":
fun main() {
    val trafficLightColor = "Red"

    if (trafficLightColor == "Red") {
        
    } 
}
  1. No corpo da instrução if, adicione uma função println() e, em seguida, transmita um argumento "Stop":
fun main() {
    val trafficLightColor = "Red"

    if (trafficLightColor == "Red") {
        println("Stop")
    } 
}
  1. Execute o programa e veja o resultado:
Stop

A expressão trafficLightColor == "Red" retorna um valor true. Portanto, a instrução println("Stop") é executada, mostrando a mensagem Stop.

Um diagrama que destaca a instrução if de trafficLightColor ==

Adicionar uma ramificação else

Agora você pode ampliar o programa para que ele informe aos motoristas que eles devem seguir quando o semáforo não estiver vermelho.

Um fluxograma que descreve uma decisão tomada quando a cor do semáforo é vermelha. Uma seta sim aponta para um

É necessário adicionar uma ramificação else para criar uma instrução if/else. Uma ramificação é uma parte incompleta do código que pode ser mesclada para formar instruções ou expressões. Uma ramificação else precisa vir depois de uma ramificação if.

Um diagrama que descreve uma instrução &quot;if/else&quot; com a palavra-chave &quot;if&quot; seguida por parênteses com uma condição dentro dela. Depois da condição, há um par de chaves com o corpo 1 dentro seguido por uma palavra-chave &quot;else&quot; seguida por parênteses. Depois disso, há duas chaves com um bloco de corpo 2 dentro.

Depois da chave de fechamento da instrução if, adicione a palavra-chave else seguida por um par de chaves. Dentro das chaves da instrução else, você pode adicionar um segundo corpo que só é executado quando a condição na ramificação if é falsa.

Adicione uma ramificação else ao programa:

  1. Depois da chave de fechamento da instrução if, adicione a palavra-chave else seguida por outro par de chaves:
fun main() {
    val trafficLightColor = "Red"

    if (trafficLightColor == "Red") {
        println("Stop")
    } else {

    }
}
  1. Dentro das chaves da palavra-chave else, adicione uma função println() e, em seguida, transmita um argumento "Go":
fun main() {
    val trafficLightColor = "Red"

    if (trafficLightColor == "Red") {
        println("Stop")
    } else {
        println("Go")
    }
}
  1. Execute o programa e veja o resultado:
Stop

O programa ainda se comporta da mesma forma que antes da ramificação else ser adicionada, mas não mostra uma mensagem Go.

  1. Reatribua a variável trafficLightColor a um valor "Green" porque você quer que os motoristas avancem no sinal verde:
fun main() {
    val trafficLightColor = "Green"

    if (trafficLightColor == "Red") {
        println("Stop")
    } else {
        println("Go")
    }
}
  1. Execute o programa e veja o resultado:
Go

Como você pode ver, agora o programa mostra uma mensagem Go (seguir) em vez de uma mensagem Stop (parar).

Um diagrama que destaca a instrução if/else com trafficLightColor ==

Você reatribuiu a variável trafficLightColor a um valor "Green". A expressão trafficLightColor == "Red" avaliada na ramificação if retorna um valor false porque o valor "Green" não é igual ao "Red".

Como resultado, o programa pula todas as instruções na ramificação if e, em vez disso, executa todas as instruções na ramificação else. Isso significa que a função println("Go") é executada, mas a função println("Stop") não.

Adicionar uma ramificação else if

Normalmente, um semáforo também tem uma cor amarela que diz para os motoristas continuarem lentamente. Você pode expandir o processo de tomada de decisão do programa para refletir isso.

Um fluxograma que descreve uma decisão tomada quando a cor do semáforo é vermelha. Uma seta sim aponta para um

Você aprendeu a escrever condicionais que atendem a um único ponto de decisão com instruções if/else que contêm um único if e uma única ramificação else. Como processar ramificações mais complexas com vários pontos de decisão? Ao enfrentar vários pontos de decisão, você precisa criar condicionais com várias camadas de condições, o que pode ser feito ao adicionar ramificações else if a instruções if/else.

Depois da chave de fechamento da ramificação if, é necessário adicionar a palavra-chave else if. Dentro dos parênteses da palavra-chave else if, você precisa adicionar uma expressão booleana como a condição para a ramificação else if seguida por um corpo dentro de um par de chaves. O corpo só vai ser executado se a condição 1 falhar, mas a condição 2 for satisfeita.

Um diagrama que descreve uma instrução &quot;if/else&quot; com a palavra-chave &quot;if&quot; seguida por parênteses com um bloco de condição 1 dentro dela. Depois da condição 1, há um par de chaves com um corpo 1.   Isso é seguido por uma palavra-chave &quot;else if&quot; com parênteses com um bloco de condição 2. Ele é seguido por um par de chaves com um bloco corpo 2 dentro.  Depois, há uma palavra-chave &quot;else&quot; com outro par de chaves com um bloco de corpo 3 dentro delas.

A ramificação else if fica sempre localizada depois da ramificação if, mas antes da ramificação else. É possível usar várias ramificações else if em uma instrução:

Um diagrama que mostra uma condição &quot;if/else&quot; com várias outras ramificações &quot;else if&quot; entre as ramificações &quot;if&quot; e &quot;else&quot;. Um texto anotado em torno das ramificações &quot;else if&quot; indicam que há várias ramificações &quot;else if&quot;.

A instrução if também pode conter a ramificação if e as ramificações else if sem nenhuma ramificação else:

Um diagrama que descreve uma instrução &quot;if/else&quot; com a palavra-chave &quot;if&quot; seguida por parênteses com um bloco de condição 1 dentro dela. Depois da condição 1, há um par de chaves com um corpo 1.   Isso é seguido por uma palavra-chave &quot;else if&quot; com parênteses e um bloco de condição 2 dentro. Ele é seguido por um par de chaves com um bloco corpo 2 dentro.

Adicione uma ramificação else if ao programa:

  1. Depois da chave de fechamento da instrução if, adicione uma expressão else if (trafficLightColor == "Yellow") seguida por chaves:
fun main() {
    val trafficLightColor = "Green"

    if (trafficLightColor == "Red") {
        println("Stop")
    } else if (trafficLightColor == "Yellow") {

    } else {
        println("Go")
    }
}
  1. Dentro das chaves da ramificação else if, adicione uma instrução println() e, em seguida, transmita um argumento de string "Slow":
fun main() {
    val trafficLightColor = "Green"

    if (trafficLightColor == "Red") {
        println("Stop")
    } else if (trafficLightColor == "Yellow") {
        println("Slow")
    } else {
        println("Go")
    }
}
  1. Reatribua a variável trafficLightColor a um valor de string "Yellow":
fun main() {
    val trafficLightColor = "Yellow"

    if (trafficLightColor == "Red") {
        println("Stop")
    } else if (trafficLightColor == "Yellow") {
        println("Slow")
    } else {
        println("Go")
    }
}
  1. Execute o programa e veja o resultado:
Slow

Agora, o programa mostra uma mensagem Slow (diminuir a velocidade), em vez de uma mensagem Stop (parar) ou Go (seguir).

<img "yellow"="" 1="" 2="" 2.="" alt="A diagram that highlights the if/else statement with the trafficLightColor == " and="" are="" as="" be="" body="" boolean="" but="" clause="" condition="" executed="" expression="" false,="" false."="" if="" in="" is="" noted="" only="" println("go")="" println("slow")="" println("stop")="" red"="" sizes="(max-width: 840px) 100vw, 856px" src="/static/codelabs/basic-android-kotlin-compose-conditionals/img/8d5e322ddf1acd52.png" srcset="/static/codelabs/basic-android-kotlin-compose-conditionals/img/8d5e322ddf1acd52_36.png 36w,/static/codelabs/basic-android-kotlin-compose-conditionals/img/8d5e322ddf1acd52_48.png 48w,/static/codelabs/basic-android-kotlin-compose-conditionals/img/8d5e322ddf1acd52_72.png 72w,/static/codelabs/basic-android-kotlin-compose-conditionals/img/8d5e322ddf1acd52_96.png 96w,/static/codelabs/basic-android-kotlin-compose-conditionals/img/8d5e322ddf1acd52_480.png 480w,/static/codelabs/basic-android-kotlin-compose-conditionals/img/8d5e322ddf1acd52_720.png 720w,/static/codelabs/basic-android-kotlin-compose-conditionals/img/8d5e322ddf1acd52_856.png 856w,/static/codelabs/basic-android-kotlin-compose-conditionals/img/8d5e322ddf1acd52_960.png 960w,/static/codelabs/basic-android-kotlin-compose-conditionals/img/8d5e322ddf1acd52_1440.png 1440w,/static/codelabs/basic-android-kotlin-compose-conditionals/img/8d5e322ddf1acd52_1920.png 1920w,/static/codelabs/basic-android-kotlin-compose-conditionals/img/8d5e322ddf1acd52_2880.png 2880w" statements="" style="width: 624.00px" the="" to="" trafficlightcolor="=" true.="" when="" />

Veja porque apenas a mensagem Slow é mostrada, e não as outras linhas:

  • Um valor "Yellow" é atribuído à variável trafficLightColor.
  • O valor "Yellow" não é igual ao valor "Red". A expressão booleana da ramificação if (identificada como 1 na imagem) retorna um valor false. O programa pula todas as instruções dentro da ramificação if e não mostra uma mensagem Stop.
  • Como a ramificação if produz um valor false, o programa continua a avaliar a expressão booleana dentro da ramificação else if.
  • O valor "Yellow" é igual ao valor "Yellow". A expressão booleana da ramificação else if (representada como 2 na imagem) retorna um valor true. O programa executa todas as instruções dentro da ramificação else if e mostra uma mensagem Slow.
  • Como a expressão booleana da ramificação else if retorna um valor true, o programa ignora o restante das ramificações. Assim, nenhuma das instruções na ramificação else é executada, e o programa não mostra uma mensagem Go.

Testar

Você percebeu que o programa atual contém um bug?

Na unidade 1, você aprendeu sobre um tipo de bug conhecido como erro de compilação, em que o Kotlin não pode compilar o código devido a um erro de sintaxe, e o programa não pode ser executado. Aqui, você enfrenta outro tipo de bug conhecido como erro de lógica, em que o programa pode ser executado, mas não produz um resultado conforme o esperado.

Supondo que você queira que os motoristas dirijam apenas quando a luz do semáforo estiver verde, o que vai acontecer se o semáforo estiver quebrado e desligado? Você quer que o motorista continue dirigindo ou receba um aviso de que algo está errado?

Infelizmente, no programa atual, se a cor do semáforo for diferente de vermelho ou amarelo, recomendamos que o motorista avance.

Corrija este problema:

  1. Reatribua a variável trafficLightColor a um valor "Black" para ilustrar um semáforo que está desligado:
fun main() {
    val trafficLightColor = "Black"

    if (trafficLightColor == "Red") {
        println("Stop")
    } else if (trafficLightColor == "Yellow") {
        println("Slow")
    } else {
        println("Go")
    }
}
  1. Execute o programa e veja o resultado:
Go

O programa mostra uma mensagem Go, mesmo que a variável trafficLightColor não receba um valor "Green". Você consegue corrigir o programa para que ele reflita o comportamento correto?

Um fluxograma que descreve uma decisão tomada quando a cor do semáforo é vermelha. Uma seta sim aponta para um

Você precisa modificar o programa para mostrar:

  • Uma mensagem Go somente quando a variável trafficLightColor é atribuída a um valor "Green".
  • Uma mensagem Invalid traffic-light color quando a variável trafficLightColor não recebe um valor "Red", "Yellow" ou "Green".

Corrigir a ramificação else

A ramificação else está sempre localizada no final de uma instrução if/else porque é uma ramificação "pega-tudo". Ela é executada automaticamente quando todas as outras condições nas ramificações anteriores não são satisfeitas. A ramificação else não é adequada quando você quer que uma ação seja executada somente quando uma condição específica for atendida. No caso do semáforo, use a ramificação else if para especificar a condição das luzes verdes.

Use a ramificação else if para avaliar a condição de semáforo verde:

  1. Depois da ramificação else if atual, adicione outra ramificação else if (trafficLightColor == "Green"):
fun main() {
    val trafficLightColor = "Black"

    if (trafficLightColor == "Red") {
        println("Stop")
    } else if (trafficLightColor == "Yellow") {
        println("Slow")
    } else if (trafficLightColor == "Green") {
        println("Go")
    }
}
  1. Execute o programa e veja o resultado.

A saída está vazia porque você não tem uma ramificação else que é executada quando as condições anteriores não são atendidas.

  1. Depois da última ramificação else if, adicione uma ramificação else com uma instrução println("Invalid traffic-light color"):
fun main() {
    val trafficLightColor = "Black"

    if (trafficLightColor == "Red") {
        println("Stop")
    } else if (trafficLightColor == "Yellow") {
        println("Slow")
    } else if (trafficLightColor == "Green") {
        println("Go")
    } else {
        println("Invalid traffic-light color")
    }

}
  1. Execute o programa e veja o resultado:
Invalid traffic-light color
  1. Atribua outro valor à variável trafficLightColor além de "Red", "Yellow" ou "Green" e, em seguida, execute o programa novamente.

Qual é o resultado do programa?

É recomendável ter uma ramificação else if explícita como validação de entrada para a cor verde e uma ramificação else para capturar outras entradas inválidas. Isso garante que os motoristas sejam instruídos a seguir, somente quando o semáforo estiver verde. Em outros casos, uma mensagem explícita de que o semáforo não está se comportando conforme o esperado é mostrada.

3. Usar uma instrução when para várias ramificações

O programa trafficLightColor parece mais complexo com várias condições, também conhecidas como ramificações. Você pode se perguntar se é possível simplificar um programa com um número ainda maior de ramificações.

Em Kotlin, ao lidar com várias ramificações, você pode usar a instrução when em vez de if/else porque ela melhora a legibilidade, ou seja, as pessoas podem ler o código com mais facilidade. É muito importante considerar a legibilidade ao escrever um programa porque é provável que outros desenvolvedores precisem revisar e modificar o código durante todo o ciclo de vida. Uma boa legibilidade garante que os desenvolvedores entendam corretamente o código e não introduzam bugs nele de forma acidental.

É recomendável usar as instruções when quando há mais de duas ramificações a serem consideradas.

Um diagrama que mostra a anatomia de uma instrução &quot;when&quot;. Ela começa com a palavra-chave &quot;when&quot; seguida por um par de chaves com um bloco de parâmetro dentro. Após o bloco, dentro de um par de chaves, há três linhas de casos. Dentro de cada linha, há um bloco de condição seguido por um símbolo de seta e um bloco de corpo. Observação: cada uma das linhas de casos é avaliada sequencialmente.

Uma instrução when aceita um único valor do parâmetro. O valor é avaliado de acordo com cada uma das condições sequencialmente. Em seguida, o corpo correspondente da primeira condição atendida é executado. Cada condição e corpo são separados por uma seta (->). Assim como as instruções if/else, cada par de condição e corpo é chamado de ramificação em instruções when. Também semelhante à instrução if/else, é possível adicionar uma ramificação else como condição final em uma instrução when que funciona como uma ramificação "pega-tudo".

Reescrever uma instrução if/else com uma instrução when

No programa do semáforo, já existem várias ramificações:

  • Semáforo vermelho
  • Semáforo amarelo
  • Semáforo verde
  • Outra cor do semáforo

Converta o programa para usar uma instrução when:

  1. Na função main(), remova a instrução if/else:
fun main() {
    val trafficLightColor = "Black"

}
  1. Adicione uma instrução when e transmita a variável trafficLightColor como um argumento:
fun main() {
    val trafficLightColor = "Black"

    when (trafficLightColor) {
    }
}
  1. No corpo da instrução when, adicione a condição "Red" seguida por uma seta e um corpo println("Stop"):
fun main() {
    val trafficLightColor = "Black"

    when (trafficLightColor) {
        "Red" -> println("Stop")
    }
}
  1. Na próxima linha, adicione a condição "Yellow" seguida por uma seta e um corpo println("Slow"):
fun main() {
    val trafficLightColor = "Black"

    when (trafficLightColor) {
        "Red" -> println("Stop")
        "Yellow" -> println("Slow")
    }
}
  1. Na próxima linha, adicione a condição "Green" seguida por uma seta e um corpo println("Go"):
fun main() {
    val trafficLightColor = "Black"

    when (trafficLightColor) {
        "Red" -> println("Stop")
        "Yellow" -> println("Slow")
        "Green" -> println("Go")
    }
}
  1. Na próxima linha, adicione a palavra-chave else seguida por uma seta e um corpo println("Invalid traffic-light color"):
fun main() {
    val trafficLightColor = "Black"

    when (trafficLightColor) {
        "Red" -> println("Stop")
        "Yellow" -> println("Slow")
        "Green" -> println("Go")
        else -> println("Invalid traffic-light color")
    }
}
  1. Reatribua a variável trafficLightColor a um valor "Yellow":
fun main() {
    val trafficLightColor = "Yellow"

    when (trafficLightColor) {
        "Red" -> println("Stop")
        "Yellow" -> println("Slow")
        "Green" -> println("Go")
        else -> println("Invalid traffic-light color")
    }
}

Qual vai ser o resultado do programa?

  1. Execute o programa e veja o resultado:
Slow

7112edfc7c7b7918.png

A saída é uma mensagem Slow porque:

  • Um valor "Yellow" é atribuído à variável trafficLightColor.
  • O programa avalia cada condição individualmente em sequência.
  • O valor "Yellow" não é igual ao valor "Red", então o programa pula o primeiro corpo.
  • O valor "Yellow" é igual ao valor "Yellow", então o programa executa o segundo corpo e mostra uma mensagem Slow.
  • Um corpo foi executado, então o programa ignora a terceira e a quarta ramificações e sai da instrução when.

Escrever condições mais complexas em uma instrução when

Até agora, você aprendeu a escrever condições when para uma única condição de igualdade, como quando a variável trafficLightColor recebe um valor "Yellow". Em seguida, você vai aprender a usar a vírgula (,) e as palavras-chave in e is para formar condições when mais complexas.

Crie um programa que determine se um número entre 1 e 10 é um número primo:

  1. Abra o Playground Kotlin em outra janela.

Vamos voltar ao programa de semáforo mais tarde.

  1. Defina uma variável x e atribua a ela um valor 3:
fun main() {
    val x = 3
}
  1. Adicione uma instrução when que inclua várias ramificações para as condições 2, 3, 5 e 7 e coloque um corpo println("x is prime number between 1 and 10.") depois de cada uma:
fun main() {
    val x = 3

    when (x) {
        2 -> println("x is a prime number between 1 and 10.")
        3 -> println("x is a prime number between 1 and 10.")
        5 -> println("x is a prime number between 1 and 10.")
        7 -> println("x is a prime number between 1 and 10.")
    }
}
  1. Adicione uma ramificação else com um corpo println("x is not prime number between 1 and 10."):
fun main() {
    val x = 3

    when (x) {
        2 -> println("x is a prime number between 1 and 10.")
        3 -> println("x is a prime number between 1 and 10.")
        5 -> println("x is a prime number between 1 and 10.")
        7 -> println("x is a prime number between 1 and 10.")
        else -> println("x isn't a prime number between 1 and 10.")
    }
}
  1. Execute o programa e verifique se o resultado está conforme o esperado:
x is a prime number between 1 and 10.

Usar uma vírgula (,) para várias condições

O programa de números primos contém muitas repetições de instruções println(). Ao escrever uma instrução when, use uma vírgula (,) para indicar várias condições que correspondem ao mesmo corpo.

Um diagrama que mostra a anatomia de uma instrução &quot;when&quot;. Ele começa com uma palavra-chave &quot;when&quot; seguida por parênteses, com um bloco de parâmetro dentro. Em seguida, dentro de um par de chaves, há duas linhas de casos. Na primeira linha, há um bloco de condição 1 seguido por uma vírgula e um bloco de condição 2 seguido por um símbolo de seta e um bloco de corpo. Na segunda linha, há um bloco de condição seguido por um símbolo de seta e um bloco de corpo.

No diagrama anterior, se a primeira ou a segunda condição for atendida, o corpo correspondente vai ser executado.

Reescreva o programa de números primos com este conceito:

  1. Na ramificação da condição 2, adicione os números 3, 5 e 7, separados por vírgulas (,):
fun main() {
    val x = 3

    when (x) {
        2, 3, 5, 7 -> println("x is a prime number between 1 and 10.")
        3 -> println("x is a prime number between 1 and 10.")
        5 -> println("x is a prime number between 1 and 10.")
        7 -> println("x is a prime number between 1 and 10.")
        else -> println("x isn't a prime number between 1 and 10.")
    }
}
  1. Remova as ramificações individuais das condições 3, 5 e 7:
fun main() {
    val x = 3

    when (x) {
        2, 3, 5, 7 -> println("x is a prime number between 1 and 10.")
        else -> println("x isn't a prime number between 1 and 10.")
    }
}
  1. Execute o programa e verifique se o resultado está conforme o esperado:
x is a prime number between 1 and 10.

Usar a palavra-chave in para várias condições

Além do símbolo de vírgula (,) para indicar várias condições, também é possível usar a palavra-chave in e um intervalo de valores em ramificações when.

Um diagrama que mostra a anatomia de uma instrução &quot;when&quot;. Ele começa com uma palavra-chave &quot;when&quot; seguida por parênteses, com um bloco de parâmetro dentro. Em seguida, dentro de um par de chaves, há duas linhas de casos. Na primeira linha, há uma palavra-chave seguida por um bloco de início do intervalo, dois pontos, um bloco final do intervalo, um símbolo de seta e um bloco de corpo. Na segunda linha, há um bloco de condição seguido por um símbolo de seta e um bloco de corpo.

Para usar um intervalo de valores, adicione um número que indique o início do intervalo seguido por dois pontos sem espaços e feche-o com outro número que indique o final do intervalo.

Quando o valor do parâmetro é igual a qualquer valor no intervalo entre o início e o fim, o primeiro corpo é executado.

No programa de números primos, é possível mostrar uma mensagem se o número estiver entre 1 e 10, mas não for um número primo?

Adicione outra ramificação com a palavra-chave in:

  1. Depois da primeira ramificação da instrução when, adicione uma segunda ramificação com a palavra-chave in, seguida por um intervalo 1..10 e um corpo println("x is a number between 1 and 10, but not a prime number."):
fun main() {
    val x = 3

    when (x) {
        2, 3, 5, 7 -> println("x is a prime number between 1 and 10.")
        in 1..10 -> println("x is a number between 1 and 10, but not a prime number.")
        else -> println("x isn't a prime number between 1 and 10.")
    }
}
  1. Mude a variável x para um valor 4:
fun main() {
    val x = 4

    when (x) {
        2, 3, 5, 7 -> println("x is a prime number between 1 and 10.")
        in 1..10 -> println("x is a number between 1 and 10, but not a prime number.")
        else -> println("x isn't a prime number between 1 and 10.")
    }
}
  1. Execute o programa e verifique o resultado:
x is a number between 1 and 10, but not a prime number.

O programa mostra a mensagem da segunda ramificação, mas não a mensagem da primeira ou da terceira.

bde4eca467c105a2.png

Veja como esse programa funciona:

  • Um valor 4 é atribuído à variável x.
  • O programa avalia as condições da primeira ramificação. O valor 4 não é o valor 2, 3, 5 ou 7. Por isso, o programa ignora a execução do corpo da primeira ramificação e passa para a segunda.
  • O valor 4 está entre 1 e 10, então a mensagem do corpo x is a number between 1 and 10, but not a prime number. é mostrada.
  • Um corpo foi executado, então o programa sai da instrução when e ignora a ramificação else.

Usar a palavra-chave is para verificar o tipo de dados

É possível usar a palavra-chave is como uma condição para verificar o tipo de dados de um valor avaliado.

Um diagrama que mostra a anatomia de uma instrução &quot;when&quot;. Ele começa com uma palavra-chave &quot;when&quot; seguida por parênteses, com um bloco de parâmetro dentro. Em seguida, dentro de um par de chaves, há duas linhas de casos. Na primeira linha, há uma palavra-chave seguida por um bloco de tipo, um símbolo de seta e, em seguida, um bloco de corpo. Na segunda linha, há um bloco de condição seguido por um símbolo de seta e um bloco de corpo.

No diagrama anterior, se o valor do argumento for do tipo de dados declarado, o primeiro corpo é executado.

No programa de números primos, é possível mostrar uma mensagem se a entrada for um número inteiro fora do intervalo de 1 a 10?

Adicione outra ramificação com a palavra-chave is:

  1. Modifique x para ser do tipo Any. Isso serve para indicar que x pode ter um valor diferente de Int.
fun main() {
    val x: Any = 4

    when (x) {
        2, 3, 5, 7 -> println("x is a prime number between 1 and 10.")
        in 1..10 -> println("x is a number between 1 and 10, but not a prime number.")
        else -> println("x isn't a prime number between 1 and 10.")
    }
}
  1. Depois da segunda ramificação da instrução when, adicione a palavra-chave is e um tipo de dados Int com um corpo println("x is an integer number, but not between 1 and 10."):
fun main() {
    val x: Any = 4

    when (x) {
        2, 3, 5, 7 -> println("x is a prime number between 1 and 10.")
        in 1..10 -> println("x is a number between 1 and 10, but not a prime number.")
        is Int -> println("x is an integer number, but not between 1 and 10.")
        else -> println("x isn't a prime number between 1 and 10.")
    }
}
  1. Na ramificação else, mude o corpo para println("x isn't an integer number.").
fun main() {
    val x: Any = 4

    when (x) {
        2, 3, 5, 7 -> println("x is a prime number between 1 and 10.")
        in 1..10 -> println("x is a number between 1 and 10, but not a prime number.")
        is Int -> println("x is an integer number, but not between 1 and 10.")
        else -> println("x isn't an integer number.")
    }
}
  1. Mude a variável x para um valor 20:
fun main() {
    val x: Any = 20

    when (x) {
        2, 3, 5, 7 -> println("x is a prime number between 1 and 10.")
        in 1..10 -> println("x is a number between 1 and 10, but not a prime number.")
        is Int -> println("x is an integer number, but not between 1 and 10.")
        else -> println("x isn't an integer number.")
    }
}
  1. Execute o programa e verifique o resultado:
x is an integer number, but not between 1 and 10.

O programa mostra a mensagem da terceira ramificação, mas não as mensagens da primeira, segunda ou quarta ramificações.

1255c101845f9247.png

O programa funciona desta forma:

  • Um valor 20 é atribuído à variável x.
  • O programa avalia as condições da primeira ramificação. O valor 20 não é um dos valores 2, 3, 5 ou 7. Por isso, o programa ignora a execução do corpo da primeira ramificação e passa para a segunda ramificação.
  • O valor 20 não está dentro do intervalo de 1 a 10. Por isso, o programa ignora a execução do corpo da segunda ramificação e passa para a terceira ramificação.
  • O valor 20 é do tipo Int, então o corpo x is an integer number, but not between 1 and 10 é mostrado.
  • Um corpo foi executado, então o programa sai da instrução when e ignora a ramificação else.

Testar

Agora, pratique o que você aprendeu no programa de semáforo.

Imagine que há uma cor de semáforo âmbar em alguns países que alerta os motoristas da mesma forma que um semáforo amarelo em outros países. Você pode modificar o programa para que essa condição adicional seja coberta mantendo as condições originais?

Adicionar outra condição com o mesmo corpo

Adicione outra condição ao programa de semáforo:

  1. Volte para a instância do Playground Kotlin com o programa de semáforo se ela ainda estiver aberta.
  2. Se você tiver fechado a página, abra uma nova instância do Playground Kotlin e insira este código:
fun main() {
    val trafficLightColor = "Yellow"

    when (trafficLightColor) {
        "Red" -> println("Stop")
        "Yellow" -> println("Slow")
        "Green" -> println("Go")
        else -> println("Invalid traffic-light color")
    }
}
  1. Na segunda ramificação da instrução when, adicione uma vírgula após a condição "Yellow" e uma condição "Amber":
fun main() {
    val trafficLightColor = "Yellow"

    when (trafficLightColor) {
        "Red" -> println("Stop")
        "Yellow", "Amber" -> println("Slow")
        "Green" -> println("Go")
        else -> println("Invalid traffic-light color")
    }
}
  1. Mude a variável trafficLightColor para um valor "Amber":
fun main() {
    val trafficLightColor = "Amber"

    when (trafficLightColor) {
        "Red" -> println("Stop")
        "Yellow", "Amber" -> println("Slow")
        "Green" -> println("Go")
        else -> println("Invalid traffic-light color")
    }
}
  1. Execute este programa e verifique o resultado:
Slow

4. Usar if/else e when como expressões

Você aprendeu a usar if/else e when como instruções. Ao usar condicionais como instruções, você permite que cada ramificação execute ações diferentes no corpo de acordo com as condições.

Também é possível usar condicionais como expressões e retornar valores diferentes para cada ramificação de condição. Quando o corpo de cada ramificação for semelhante, você pode usar expressões condicionais para melhorar a legibilidade do código em comparação com instruções condicionais.

Um diagrama que descreve uma expressão if/else com a palavra-chave &quot;val&quot; seguida por um bloco de nome, um símbolo de igual, uma palavra-chave &quot;if&quot;, parênteses com uma condição dentro deles, um par de chaves com um bloco de corpo 1 dentro delas, uma palavra-chave &quot;else&quot; e um par de chaves com um bloco de corpo dentro delas.

A sintaxe de condicionais como expressões é semelhante às instruções, mas a última linha dos corpos em cada ramificação precisa retornar um valor ou uma expressão e os condicionais são atribuídos a uma variável.

Se os corpos tiverem apenas uma expressão ou um valor de retorno, é possível remover as chaves para deixar o código mais conciso.

Um diagrama que descreve uma expressão if/else com a palavra-chave val seguida por um bloco de nome, um símbolo de igual, uma palavra-chave if, parênteses com uma condição dentro, um bloco de expressão 1, uma palavra-chave else e um bloco de expressão 2.

Na próxima seção, você vai ver as expressões if/else no programa de semáforo.

Converter uma instrução if em uma expressão

Há muitas repetições de println() nesta instrução if/else:

fun main() {
    val trafficLightColor = "Black"

    if (trafficLightColor == "Red") {
        println("Stop")
    } else if (trafficLightColor == "Yellow") {
        println("Slow")
    } else if (trafficLightColor == "Green") {
        println("Go")
    } else {
        println("Invalid traffic-light color")
    }

}

Converta a instrução if/else em uma expressão if/else e remova a repetição:

  1. No Playground Kotlin, abra o programa de semáforo anterior.
  2. Defina uma variável message e atribua uma instrução if/else a ela:
fun main() {
    val trafficLightColor = "Black"

    val message = if (trafficLightColor == "Red") {
        println("Stop")
    } else if (trafficLightColor == "Yellow") {
        println("Slow")
    } else if (trafficLightColor == "Green") {
        println("Go")
    } else {
        println("Invalid traffic-light color")
    }

}
  1. Remova todas as instruções println() e as chaves, mas deixe os valores dentro delas:
fun main() {
    val trafficLightColor = "Black"

    val message = 
      if (trafficLightColor == "Red") "Stop"
      else if (trafficLightColor == "Yellow") "Slow"
      else if (trafficLightColor == "Green") "Go"
      else "Invalid traffic-light color"
}
  1. Adicione uma instrução println() ao final do programa e transmita a variável message como um argumento:
fun main() {
    val trafficLightColor = "Black"

    val message = 
      if (trafficLightColor == "Red") "Stop"
      else if (trafficLightColor == "Yellow") "Slow"
      else if (trafficLightColor == "Green") "Go"
      else "Invalid traffic-light color"

    println(message)
}
  1. Execute o programa e veja o resultado:
Invalid traffic-light color

Testar

Converta o programa de semáforo para usar uma expressão when em vez de uma instrução when:

  1. No Playground Kotlin, digite este código:
fun main() {
    val trafficLightColor = "Amber"

    when (trafficLightColor) {
        "Red" -> println("Stop")
        "Yellow", "Amber" -> println("Slow")
        "Green" -> println("Go")
        else -> println("Invalid traffic-light color")
    }
}

É possível converter a instrução when em uma expressão para não repetir as instruções println()?

  1. Crie uma variável message e a atribua à expressão when:
fun main() {
    val trafficLightColor = "Amber"

    val message = when(trafficLightColor) {
        "Red" -> "Stop"
        "Yellow", "Amber" -> "Slow"
        "Green" -> "Go"
        else -> "Invalid traffic-light color"
    }
}
  1. Adicione uma instrução println() como a última linha do programa e transmita a variável message como um argumento:
fun main() {
    val trafficLightColor = "Amber"

    val message = when(trafficLightColor) {
        "Red" -> "Stop"
        "Yellow", "Amber" -> "Slow"
        "Green" -> "Go"
        else -> "Invalid traffic-light color"
    }
    println(message)
}

5. Conclusão

Parabéns! Você aprendeu sobre condicionais e como criá-los em Kotlin.

Resumo

  • Em Kotlin, a ramificação pode ser feita com condicionais if/else ou when.
  • O corpo de uma ramificação if em um condicional if/else é executado apenas quando a expressão booleana dentro da condição if da ramificação retorna um valor true.
  • As ramificações else if seguintes em um condicional if/else são executadas somente quando ramificações if ou else if anteriores retornam valores false.
  • A ramificação else final em um condicional if/else só é executada quando todas as ramificações if ou else if anteriores retornam valores false.
  • É recomendável usar o condicional when para substituir um condicional if/else quando há mais de duas ramificações.
  • É possível escrever condições mais complexas em condicionais when com vírgulas (,), intervalos in e a palavra-chave is.
  • Os condicionais if/else e when podem funcionar como instruções ou expressões.

Saiba mais