Lambda é uma função anônima representada como uma expressão compacta { argumentos -> corpo }. Em Kotlin, lambdas são a principal forma de passar comportamento para funções de ordem superior, fornecendo sintaxe concisa sem declarar uma função separada. De acordo com a documentação do Kotlin (2026), mais de 70% das funções de ordem superior em projetos típicos são chamadas com lambdas. Lambda permite escrever código em estilo funcional com mínimo ruído sintático.
Pontos principais
Lambda (expressão lambda) é uma função anônima definida como uma expressão em vez de uma declaração. O termo origina-se do cálculo lambda de Alonzo Church (1936). Em programação, uma lambda é um bloco de código que pode ser passado como valor, armazenado em uma variável e chamado posteriormente. Em Kotlin, uma lambda está sempre entre chaves { }, com os argumentos separados do corpo pela seta ->.
Uma lambda difere de uma função regular pela ausência de nome e da palavra-chave fun. Isso permite declarar comportamento diretamente no ponto de uso, sem poluir o código com declarações adicionais. O compilador Kotlin infere os tipos dos argumentos a partir do contexto, então em muitos casos os tipos podem ser omitidos. Uma lambda é açúcar sintático sobre o tipo funcional (T) -> R: toda lambda tem um tipo funcional correspondente.
O uso principal de lambdas em Kotlin é passá-las para funções de ordem superior. A biblioteca padrão usa lambdas em toda parte: filter { it > 0 }, map { it.uppercase() }, forEach { println(it) }. Lambdas também são usadas para listeners de eventos, callbacks e configuradores de objetos através de apply e run, tornando o código mais declarativo comparado a classes anônimas.
A forma completa de uma expressão lambda em Kotlin: { argumentos -> corpo_lambda }. Os argumentos são listados separados por vírgulas, seguidos por uma seta e o corpo — uma ou mais expressões. Se o corpo contiver várias linhas, a última expressão torna-se o valor de retorno. Se uma função aceita uma lambda como seu último argumento, ela pode ser movida para fora dos parênteses de chamada.
val sum: (Int, Int) -> Int = { a, b -> a + b }
// Tipos inferidos do contexto
val sumShort = { a: Int, b: Int -> a + b }
// Chamada lambda
val result = sum(5, 3) // 8
println(result)
A variável sum é declarada com um tipo funcional explícito (Int, Int) -> Int e inicializada com uma lambda { a, b -> a + b }. Para sumShort, os tipos são especificados dentro da lambda e o tipo da variável é inferido. Ambas as variantes são equivalentes. Chamar uma lambda não é diferente de chamar uma função regular — usando a sintaxe sum(5, 3). Uma lambda sem argumentos é escrita como { body }, com um argumento — { it -> it * 2 } ou simplesmente { it * 2 }.
Quando uma lambda aceita exatamente um argumento, Kotlin fornece o nome implícito it. Isso elimina a necessidade de declarar o argumento no lado esquerdo. O desenvolvedor escreve apenas o corpo da lambda, usando it para acessar o único parâmetro. Esta sintaxe é especialmente conveniente em cadeias de processamento de coleções, onde it se refere ao elemento atual.
val numbers = listOf(1, 2, 3, 4, 5)
// Nome de parâmetro explícito
val squaredExplicit = numbers.map { n -> n * n }
// it implícito
val squared = numbers.map { it * it }
// Filtrando com it
val even = numbers.filter { it % 2 == 0 }
println(squared) // [1, 4, 9, 16, 25]
No exemplo, map { it * it } usa it em vez de declarar n ->. Kotlin atribui automaticamente it para um único parâmetro lambda. Se uma lambda aceita dois ou mais argumentos, it não é criado — todos os parâmetros devem ser declarados explicitamente. Para melhor legibilidade de lambdas aninhadas, vale a pena dar nomes significativos aos parâmetros e usar it apenas em predicados curtos de uma linha.
Trailing lambda é um recurso sintático do Kotlin que permite mover o último argumento lambda para fora dos parênteses de chamada da função. Isso faz o código se assemelhar a construções de linguagem integradas. Se a lambda for o único argumento, os parênteses podem ser omitidos completamente. Esta abordagem é ativamente usada na biblioteca padrão e DSLs.
// Chamada padrão
thread(block = {
println("Olá da thread")
})
// Versão trailing lambda
thread {
println("Olá da thread")
}
// repeat com trailing lambda
repeat(3) { index ->
println("Iteração $index")
}
// executar com lambda multilinha
val config = run {
val host = "localhost"
val port = 8080
"$host:$port"
}
A função thread aceita um Runnable como último argumento. Graças ao trailing lambda, a lambda pode ser passada fora dos parênteses, assemelhando-se visualmente a um bloco de código. A função repeat recebe um número de iterações e uma lambda com um índice. run é um exemplo de função de ordem superior onde uma lambda multilinha calcula um valor retornado pela última expressão. Os parênteses em torno de run() podem ser omitidos se a lambda for o único argumento.
Captura de variáveis (closure) é a capacidade de uma lambda acessar variáveis declaradas no escopo externo. Em Kotlin, uma lambda pode ler e modificar variáveis var, bem como ler variáveis val do contexto circundante. Variáveis capturadas são armazenadas com a lambda durante todo o seu ciclo de vida, permitindo criar funções com estado.
fun makeCounter(): () -> Int {
var count = 0
return {
count++ // capturas count
}
}
fun main() {
val counter = makeCounter()
println(counter()) // 0
println(counter()) // 1
println(counter()) // 2
}
A função makeCounter declara uma variável local count e retorna uma lambda { count++ }. Embora makeCounter tenha concluído a execução, a lambda retornada mantém uma referência a count através da clausura. Cada chamada a counter() incrementa e retorna o valor atual. O mecanismo de closure fundamenta currying, fábricas de funções e memoização. É importante lembrar que capturar variáveis mutáveis pode levar a comportamento inesperado em execução concorrente.
Perguntas frequentes
Lambda não suporta return incondicional — um return sem rótulo retorna o controle para a função externa. Para sair de uma lambda, use return@label, onde label é o nome da função de ordem superior para a qual a lambda foi passada.
Uma função anônima é escrita como fun(a: Int): Int { return a * 2 } e suporta return sem rótulo. Uma lambda { a -> a * 2 } é mais curta em sintaxe mas requer return@label para saída antecipada.
Se uma lambda não aceita argumentos, a seta é omitida: { body() }. Se aceita um argumento mas não o usa, escreva { _ -> body() } com um sublinhado para ignorar o parâmetro.
Sim, toda lambda passada para uma função não inline cria uma instância de uma classe anônima. Para funções inline, a lambda é embutida no local da chamada sem criar um objeto. Lambdas que não capturam são armazenadas em cache como objetos singleton.
Return em Kotlin é um operador de salto pertencente à função mais próxima declarada com fun. Uma lambda não é uma função (fun), mas uma expressão. Portanto, um return dentro de uma lambda sem rótulo é tratado como um retorno da função externa circundante.
Resumo
Vamos desenvolver um aplicativo móvel chave na mão
A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.
Leia também