O que é when em Kotlin?

O when é a versão turbinada do switch em Kotlin. Ele funciona tanto como expressão (retorna valor) quanto como instrução (executa blocos). É mais poderoso e flexível que o switch de Java ou C — suporta ranges, verificações de tipo, condições complexas e muito mais.

Sintaxe básica

fun classificarNota(nota: Int): String {
    return when (nota) {
        10 -> "Perfeito!"
        in 7..9 -> "Aprovado"
        in 5..6 -> "Recuperação"
        in 0..4 -> "Reprovado"
        else -> "Nota inválida"
    }
}

fun main() {
    println(classificarNota(8))  // Aprovado
    println(classificarNota(3))  // Reprovado
}

When como expressão

Quando when é usado como expressão (retornando valor), o else é obrigatório — a menos que o compilador consiga verificar que todos os casos estão cobertos:

enum class DiaSemana { SEG, TER, QUA, QUI, SEX, SAB, DOM }

fun tipoDeDia(dia: DiaSemana) = when (dia) {
    DiaSemana.SEG, DiaSemana.TER, DiaSemana.QUA,
    DiaSemana.QUI, DiaSemana.SEX -> "Dia útil"
    DiaSemana.SAB, DiaSemana.DOM -> "Fim de semana"
}

Verificação de tipo com is

fun descrever(obj: Any): String = when (obj) {
    is String -> "Texto com ${obj.length} caracteres"
    is Int -> "Número inteiro: $obj"
    is List<*> -> "Lista com ${obj.size} itens"
    is Boolean -> if (obj) "Verdadeiro" else "Falso"
    else -> "Tipo desconhecido"
}

fun main() {
    println(descrever("Kotlin"))        // Texto com 6 caracteres
    println(descrever(42))              // Número inteiro: 42
    println(descrever(listOf(1, 2, 3))) // Lista com 3 itens
}

Repare que dentro de cada branch, o smart cast já aplica o tipo automaticamente.

When sem argumento

Você pode usar when sem argumento, funcionando como uma cadeia de if-else:

fun avaliarTemperatura(temp: Double): String = when {
    temp < 0 -> "Congelante!"
    temp < 15 -> "Tá frio, hein"
    temp < 25 -> "Temperatura agradável"
    temp < 35 -> "Tá quente"
    else -> "Derretendo!"
}

fun main() {
    println(avaliarTemperatura(28.0)) // Tá quente
}

When com sealed class

A combinação com sealed class é perfeita — o compilador garante que todos os casos são tratados, sem precisar de else. Essa é uma das duplas mais poderosas do Kotlin pra modelar estados e resultados.