CodeGym /Cursos /Kotlin SELF /if como expressao em Kotlin: atribuindo o resultado do de...

if como expressao em Kotlin: atribuindo o resultado do desvio

Kotlin SELF
Nível 3, Lição 5
Disponível

1. Introducao

Se voce acabou de dominar o if, o cerebro ainda o enxerga como uma “encruzilhada”: se a condicao e verdadeira — vamos para a esquerda e fazemos algo; caso contrario — para a direita e tambem fazemos algo. E isso e normal. Mas, em programas reais, muitas vezes precisamos nao apenas “fazer uma acao”, e sim obter o resultado da escolha: uma string, um numero, um rotulo, que depois vamos usar adiante.

Imagine que voce esta escolhendo qual placa pendurar na porta: "Aberto" ou "Fechado". Isso nao e uma acao isolada por si so — e um valor que precisa ser guardado e depois exibido. Kotlin, nesse ponto, diz: “Ok, deixe o if ja devolver a placa”. E isso e muito conveniente.

if como operador e if como expressao

Quando escrevemos if “do jeito antigo”, ele funciona como um operador (statement): executa ou nao executa um trecho de codigo, e pronto.

Mas Kotlin permite usar if como expressao (expression), ou seja, como algo que tem valor, como 3 + 4 ou "Hi".length. Isso e parte oficial da linguagem: if pode ser escrito como expressao e ter seu resultado atribuido a uma variavel, mas entao o ramo else passa a ser obrigatorio.

Para pegar a ideia, vamos comparar dois estilos — “primeiro criei uma caixa (var), depois coloquei o resultado dentro” e “obtive o resultado diretamente”.

Aqui esta o estilo que voce ja conhece (o if como statement):

fun main() {
    val temperature = 28

    var label = "Normal"
    if (temperature > 25) {
        label = "Quente"
    }

    println(label) // Quente
}

Aqui o if nao “retorna” nada. Nos apenas mudamos label.

E aqui esta o estilo que queremos dominar hoje (o if como expressao):

fun main() {
    val temperature = 28

    val label = if (temperature > 25) "Quente" else "Normal"
    println(label) // Quente
}

A diferenca de sentido e esta: no segundo caso, nos dizemos diretamente ao Kotlin: “label e o resultado da escolha”.

Sintaxe basica: val x = if (cond) A else B

A forma basica e: val result = if (condicao) valor1 else valor2. Ela se le quase como uma frase humana: “result e igual a (se a condicao, entao valor1; caso contrario, valor2)”.


val result = if (condition) value1 else value2
Sintaxe basica: if como expressao

Um exemplo que sempre funciona bem e o modulo de um numero (valor absoluto). Em matematica isso e |x|; no codigo, nos apenas escolhemos: ou x, ou -x.

fun main() {
    val x = -7

    val abs = if (x >= 0) x else -x
    println("abs = $abs") // abs = 7
}

Repare: aqui nao usamos var em nenhum momento. E uma pequena, mas importante vitoria: menos variaveis mutaveis — menos lugares onde da para “quebrar tudo sem querer”.

Por que else e obrigatorio

Do ponto de vista de quem esta comecando, a exigencia “por que eu nao posso escrever val r = if (cond) 1?” parece implicancia. Mas o compilador nao esta sendo chato; ele esta cuidando da logica: se voce atribui um resultado, entao o resultado precisa existir sempre, para qualquer desfecho da condicao.

Em Kotlin esta dito explicitamente: se if for usado como expressao, o ramo else e obrigatorio.

Exemplo ruim (nao pode):

fun main() {
    val isVip = true
    val discount = if (isVip) 10 // Erro de compilacao: nao ha else
}

Exemplo bom (correto):

fun main() {
    val isVip = true

    val discount = if (isVip) 10 else 0
    println("discount = $discount") // discount = 10
}

Aqui e conveniente memorizar a regra: se o if estiver a direita de = e voce quer guardar o resultado, entao o else e sempre obrigatorio.

Ramos em bloco { ... }: o valor e a ultima expressao

Muitas vezes, dentro do ramo, precisamos fazer mais de uma coisa: por exemplo, imprimir uma explicacao e so depois retornar um valor. Kotlin permite que cada ramo seja um bloco { ... }. Entao, o resultado do ramo passa a ser a ultima expressao do bloco.

Vamos fazer um mini-exemplo: escolher quem considerar “mais alto” — Alice ou Bob — e, ao mesmo tempo, imprimir quem foi escolhido (como se fosse um log).

fun main() {
    val heightAlice = 160
    val heightBob = 175

    val taller = if (heightAlice > heightBob) {
        println("Escolhemos Alice") // Escolhemos Alice (se a condicao fosse true)
        heightAlice
    } else {
        println("Escolhemos Bob")  // Escolhemos Bob
        heightBob
    }

    println("taller = $taller") // taller = 175
}

Note o “truque”: println(...) nao e o valor de taller. O valor e a ultima linha do ramo (heightAlice ou heightBob). Isso e um habito muito importante: no fim do ramo do if-expressao deve estar exatamente aquilo que voce quer retornar.

Um pequeno esquema de como isso funciona

flowchart TD
    A["if (condicao)"] -->|true| B["ramo then { ... }"]
    A -->|false| C["ramo else { ... }"]
    B --> D["valor = ultima expressao do ramo then"]
    C --> E["valor = ultima expressao do ramo else"]
    D --> F["resultado da expressao if"]
    E --> F

2. else if e o estilo de codigo linear

As vezes nao temos “duas opcoes”, mas “tres ou quatro”. E a boa noticia: a cadeia if / else if / else tambem pode ser uma expressao. Ou seja, podemos atribuir o resultado imediatamente, sem var intermediarios.

Exemplo: temos um numero x e queremos obter uma string "positive", "negative" ou "zero".

fun main() {
    val x = 0

    val sign = if (x > 0) {
        "positive"
    } else if (x < 0) {
        "negative"
    } else {
        "zero"
    }

    println(sign) // zero
}

Esse estilo e especialmente bom porque a variavel sign ja nasce com um sentido claro: “este e o rotulo do sinal do numero”.

Como a expressao if ajuda a deixar o codigo “linear”

Antes das expressoes if, e comum escrever assim: “declarei uma variavel var, depois atribuo em ramos diferentes”. E uma abordagem funcional, mas aos poucos leva a variavel a viver tempo demais e ser alterada muitas vezes.

Vamos comparar duas abordagens em uma tarefa do dia a dia: se a string estiver vazia — substitui-la por "EMPTY"; caso contrario, deixar como esta (apos trim()).

Abordagem com var:

fun main() {
    val raw = "   Kotlin   "
    val trimmed = raw.trim()

    var label = "EMPTY"
    if (trimmed.length != 0) {
        label = trimmed
    }

    println(label) // Kotlin
}

Abordagem com if-expressao:

fun main() {
    val raw = "   Kotlin   "
    val trimmed = raw.trim()

    val label = if (trimmed.length == 0) "EMPTY" else trimmed
    println(label) // Kotlin
}

O segundo caso e lido mais rapido: “label e ou "EMPTY", ou trimmed”. E o principal: agora label e val, ou seja, “a placa na porta” nao pode ser alterada no meio do programa por acidente.

3. Exemplo pratico: “Caixa com desconto”

Agora vamos montar um pequeno programa de console que parece um cenario real: o usuario digita o valor do pedido, e nos calculamos o desconto e imprimimos o total. E um exercicio honesto, no qual da para ver onde o if como expressao deixa o codigo mais simples.

A ideia e esta:

1) lemos o valor (como string), removemos espacos, tentamos fazer parse para numero com toIntOrNull();
2) se nao for numero — imprimimos uma mensagem de erro;
3) se for numero — definimos o percentual de desconto: se o valor >= 1000, entao o desconto e 10%, senao 0%;
4) montamos a mensagem e imprimimos.

Passo 1. Escolher o percentual de desconto como valor

Vamos comecar pelo mais importante para esta aula — atribuir o resultado do desvio:

fun main() {
    val sum = 1200

    val discountPercent = if (sum >= 1000) 10 else 0
    println("discountPercent = $discountPercent") // discountPercent = 10
}

Aqui fica clara a ideia principal: discountPercent e o resultado de uma escolha; portanto, a expressao if se encaixa perfeitamente.

Passo 2. A mensagem tambem pode ser “calculada”

Iniciantes muitas vezes fazem assim: em cada ramo do if, imprimem um texto quase igual. Funciona, mas rapidamente leva a duplicacao. Em vez disso, podemos calcular a string message, e deixar a impressao em uma unica linha.

fun main() {
    val finalSum = 950
    val discountPercent = 0

    val message = if (discountPercent > 0) {
        "Desconto de $discountPercent% aplicado. Total: $finalSum"
    } else {
        "Sem desconto. Total: $finalSum"
    }

    println(message) // Sem desconto. Total: 950
}

Repare: usamos blocos { ... }, mas a ultima linha e exatamente uma string, e nao um println.

Passo 3. Versao completa do main

Abaixo esta um exemplo completo. Ele e um pouco mais longo do que os trechos isolados (porque um programa real ainda faz entrada/validacoes), mas todas as tecnicas aqui ja sao conhecidas.

fun main() {
    print("Digite o valor do pedido: ")
    val sumText = readln().trim()
    val sum = sumText.toIntOrNull()

    if (sum == null) {
        println("Erro: e preciso digitar um numero inteiro.") // Erro: e preciso digitar um numero inteiro.
    } else {
        val discountPercent = if (sum >= 1000) 10 else 0
        val discount = sum * discountPercent / 100
        val finalSum = sum - discount

        val message = if (discountPercent > 0) {
            "Desconto de $discountPercent% (-$discount). Total: $finalSum"
        } else {
            "Sem desconto. Total: $finalSum"
        }

        println(message) // exemplo: Desconto de 10% (-120). Total: 1080
    }
}

Aqui existe um estilo importante de pensamento: tentamos fazer as variaveis virarem “fatos de uso unico”. discountPercent, discount, finalSum, message nao sao “caixas que mudam”, e sim “resultados de calculos”. Quando voce se acostuma com isso, o codigo fica mais previsivel: voce o le de cima para baixo, como uma receita.

1
Tarefa
Kotlin SELF, nível 3, lição 5
Bloqueado
Módulo da dívida
Módulo da dívida
1
Tarefa
Kotlin SELF, nível 3, lição 5
Bloqueado
Placa da porta
Placa da porta
1
Tarefa
Kotlin SELF, nível 3, lição 5
Bloqueado
Classificação do jogador
Classificação do jogador
1
Tarefa
Kotlin SELF, nível 3, lição 5
Bloqueado
Apelido sem espaços
Apelido sem espaços
1
Pesquisa/teste
Operadores condicionais e logica, nível 3, lição 5
Indisponível
Operadores condicionais e logica
Operadores condicionais e logica
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION