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.