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
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.
GO TO FULL VERSION