O que é inline em Kotlin?

O modificador inline em Kotlin instrui o compilador a copiar o corpo da função diretamente no local da chamada, em vez de criar uma chamada de função normal. Isso elimina o overhead de criação de objetos para lambdas, melhorando a performance.

Toda vez que você passa uma lambda como argumento, o Kotlin normalmente cria um objeto anônimo. Com inline, esse objeto não é criado — o código da lambda é copiado diretamente.

Sem inline vs com inline

// Sem inline: cria um objeto Function para cada chamada
fun semInline(bloco: () -> Unit) {
    bloco()
}

// Com inline: código é copiado no local da chamada
inline fun comInline(bloco: () -> Unit) {
    bloco()
}

Na prática, o resultado é o mesmo. A diferença é por baixo dos panos: a versão inline não aloca um objeto Function.

Exemplo prático: medindo tempo

inline fun medirTempo(bloco: () -> Unit) {
    val inicio = System.currentTimeMillis()
    bloco()
    val fim = System.currentTimeMillis()
    println("Tempo: ${fim - inicio}ms")
}

fun main() {
    medirTempo {
        val soma = (1..1_000_000).sum()
        println("Soma: $soma")
    }
}

Non-local return

Uma vantagem do inline é permitir non-local return — retornar da função que chamou, não só da lambda:

inline fun buscarPrimeiro(lista: List<Int>, condicao: (Int) -> Boolean): Int? {
    for (item in lista) {
        if (condicao(item)) return item
    }
    return null
}

fun main() {
    val resultado = buscarPrimeiro(listOf(1, 3, 5, 8, 10)) { it % 2 == 0 }
    println(resultado) // 8
}

noinline e crossinline

Se a função tem vários parâmetros lambda e você não quer inlinear todos:

inline fun exemplo(
    inlineada: () -> Unit,
    noinline naoInlineada: () -> Unit
) {
    inlineada()
    naoInlineada()
}

E crossinline impede non-local return em lambdas que serão executadas em outro contexto.

Quando usar?

Use inline em funções que recebem lambdas como parâmetro e são chamadas com frequência. A biblioteca padrão do Kotlin usa inline em let, apply, map, filter e praticamente todas as scope functions.