Lambda: o que é, sintaxe e uso em Kotlin

Autor: IT Sectr Publicado: 2026-06-23 Tempo de leitura: 7 min

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 — uma função anônima na sintaxe { args -> body }, sem nome
  • it implícito substitui o único argumento de uma lambda, simplificando a escrita
  • Trailing lambda — mover a última lambda para fora dos parênteses de chamada para legibilidade
  • Clausura (closure) — uma lambda pode acessar variáveis do escopo externo
  • Tipo funcional (T) -> R define a assinatura da lambda e é verificado pelo compilador

O que é lambda?

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.

Sintaxe de expressões lambda em Kotlin

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.

kotlin
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 }.

it implícito e omissão de argumentos

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.

kotlin
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 e lambdas multilinha

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.

kotlin
// 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) em lambdas

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.

kotlin
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

Uma lambda pode ter return?

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.

Qual a diferença entre lambda e função anônima?

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.

Como passar uma lambda como argumento sem seta?

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.

Uma lambda sempre cria um novo objeto?

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.

Por que não se pode usar return diretamente em uma lambda?

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

  • Lambda — função anônima na sintaxe { args -> body }, passada como valor para funções de ordem superior
  • it implícito substitui o único argumento, tornando o código mais compacto em predicados curtos
  • Trailing lambda move a última lambda para fora dos parênteses de chamada, lendo-se como um bloco de código
  • Clausura (closure) permite a uma lambda acessar variáveis do contexto externo após a conclusão da função contêiner
  • Tipo funcional (T) -> R define a assinatura da lambda com verificação em tempo de compilação
  • Funções inline eliminam a criação de classes anônimas para lambdas, melhorando o desempenho em loops
  • Lambdas multilinha retornam o valor da última expressão, suportando computações complexas sem declarar uma função separada

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.

Discutir o projeto

Leia também