---
title: "Kotlin Context Receivers e Context Parameters: Guia Prático | Kotlin Brasil"
url: "https://kotlin.dev.br/blog/kotlin-context-receivers-parameters/"
markdown_url: "https://kotlin.dev.br/blog/kotlin-context-receivers-parameters.MD"
description: "Aprenda a usar Context Receivers e Context Parameters em Kotlin com exemplos práticos. Guia completo sobre injeção de contexto implícito."
date: "2026-03-31"
author: "Karina Melo"
---

# Kotlin Context Receivers e Context Parameters: Guia Prático | Kotlin Brasil

Aprenda a usar Context Receivers e Context Parameters em Kotlin com exemplos práticos. Guia completo sobre injeção de contexto implícito.


Se você já trabalhou com [extension functions](/blog/extension-functions-kotlin/) em Kotlin, sabe como elas tornam o código mais expressivo. Mas e quando uma função precisa de **múltiplos contextos** ao mesmo tempo? É aí que entram os **Context Receivers** e sua evolução, os **Context Parameters**. Neste guia, vamos explorar como essas funcionalidades transformam a forma de escrever código Kotlin.

## O que são Context Receivers?

Context Receivers foram introduzidos experimentalmente no Kotlin 1.6.20 como uma forma de declarar que uma função precisa de um ou mais **contextos implícitos** para ser chamada. Diferente de extension functions, que possuem apenas um receiver, os context receivers permitem múltiplos.

A ideia central é simples: em vez de passar dependências explicitamente como parâmetros, você declara que a função **requer** um determinado contexto para funcionar.

### Sintaxe básica

```kotlin
context(LoggerContext)
fun processarPedido(pedido: Pedido) {
    log("Processando pedido ${pedido.id}")
    // lógica de processamento
}

interface LoggerContext {
    fun log(mensagem: String)
}
```

Para chamar essa função, o chamador precisa estar em um escopo onde `LoggerContext` esteja disponível:

```kotlin
class ServicoDeVendas : LoggerContext {
    override fun log(mensagem: String) {
        println("[VENDAS] $mensagem")
    }

    fun vender(pedido: Pedido) {
        processarPedido(pedido) // funciona! LoggerContext está no escopo
    }
}
```

## Context Receivers vs Extension Functions

Você pode estar pensando: "Isso parece uma extension function". E de fato a motivação é semelhante, mas existem diferenças cruciais:

| Aspecto | Extension Function | Context Receiver |
|---|---|---|
| Receivers | Apenas 1 | Múltiplos |
| Acesso ao `this` | Sim, do receiver | Sim, de cada contexto |
| Uso primário | Adicionar métodos a tipos | Injeção de contexto implícito |
| Combinação | Difícil combinar múltiplos | Natural com múltiplos contextos |

### Exemplo prático com múltiplos contextos

```kotlin
interface TransactionContext {
    fun <T> executarTransacao(bloco: () -> T): T
}

interface NotificacaoContext {
    fun notificar(usuario: String, mensagem: String)
}

context(TransactionContext, NotificacaoContext, LoggerContext)
fun transferirSaldo(origem: Conta, destino: Conta, valor: Double) {
    log("Iniciando transferência de R$$valor")
    executarTransacao {
        origem.debitar(valor)
        destino.creditar(valor)
    }
    notificar(origem.titular, "Transferência de R$$valor realizada")
    log("Transferência concluída com sucesso")
}
```

Esse código é limpo, sem precisar passar cada dependência como parâmetro. Se você trabalha com <a href="https://python.dev.br/blog/" target="_blank" rel="noopener" onclick="umami.track('portfolio-site-click', { destination: 'python.dev.br' })">Python e decorators</a>, vai notar uma semelhança conceitual: ambos permitem injetar comportamento de forma declarativa, embora com mecanismos bem diferentes.

## De Context Receivers para Context Parameters

A equipe do Kotlin percebeu que a implementação original de context receivers tinha limitações. Por isso, a partir do Kotlin 2.0+, a funcionalidade está evoluindo para **Context Parameters** — uma abordagem mais refinada e segura.

### Principais diferenças

```kotlin
// Context Receivers (experimental, Kotlin 1.6.20+)
context(LoggerContext)
fun processarPedido(pedido: Pedido) { ... }

// Context Parameters (evolução futura)
fun processarPedido(context logger: LoggerContext, pedido: Pedido) { ... }
```

Com context parameters, o contexto é declarado de forma mais explícita na assinatura da função, tornando o código mais previsível e fácil de entender. As vantagens incluem:

- **Nomeação explícita**: cada contexto tem um nome, evitando ambiguidades
- **Melhor inferência de tipos**: o compilador K2 trabalha melhor com essa sintaxe
- **Compatibilidade com IDE**: melhor autocomplete e navegação no IntelliJ IDEA

## Casos de uso práticos

### 1. Injeção de dependências leve

Context receivers oferecem uma forma de injeção de dependências sem frameworks pesados como [Koin ou Dagger](/comparacoes/koin-vs-dagger/):

```kotlin
interface RepositorioPedidos {
    fun buscarPorId(id: Long): Pedido?
    fun salvar(pedido: Pedido): Pedido
}

interface ServicoPagamento {
    fun processar(valor: Double, metodo: MetodoPagamento): ResultadoPagamento
}

context(RepositorioPedidos, ServicoPagamento, LoggerContext)
fun finalizarCompra(pedidoId: Long, metodo: MetodoPagamento): ResultadoCompra {
    val pedido = buscarPorId(pedidoId) ?: error("Pedido não encontrado")
    log("Processando pagamento para pedido $pedidoId")

    val resultado = processar(pedido.total, metodo)

    if (resultado.sucesso) {
        salvar(pedido.copy(status = Status.PAGO))
        log("Pedido $pedidoId pago com sucesso")
    }

    return ResultadoCompra(pedidoId, resultado)
}
```

### 2. Construção de DSLs mais expressivas

Se você já leu nosso guia sobre [DSLs em Kotlin](/blog/kotlin-dsl/), sabe que lambdas com receiver são essenciais. Context receivers levam isso a outro nível:

```kotlin
interface HtmlContext {
    fun tag(nome: String, conteudo: String)
}

interface CssContext {
    fun estilo(seletor: String, propriedades: Map<String, String>)
}

context(HtmlContext, CssContext)
fun componenteCartao(titulo: String, descricao: String) {
    estilo(".cartao", mapOf(
        "border-radius" to "8px",
        "padding" to "16px",
        "box-shadow" to "0 2px 4px rgba(0,0,0,0.1)"
    ))
    tag("div", """
        <h3>$titulo</h3>
        <p>$descricao</p>
    """)
}
```

### 3. Logging e monitoramento com contexto

Uma aplicação prática e comum é adicionar contexto de [observabilidade](/blog/kotlin-observabilidade/) sem poluir assinaturas de funções:

```kotlin
interface TracingContext {
    val traceId: String
    fun span(nome: String, bloco: () -> Unit)
}

context(TracingContext, LoggerContext)
fun processarEvento(evento: Evento) {
    span("processar-evento") {
        log("[$traceId] Evento recebido: ${evento.tipo}")
        // processamento do evento
    }
}
```

## Como habilitar Context Receivers hoje

Para experimentar context receivers no seu projeto, adicione ao `build.gradle.kts`:

```kotlin
tasks.withType<KotlinCompile> {
    compilerOptions {
        freeCompilerArgs.add("-Xcontext-receivers")
    }
}
```

> **Atenção**: Context receivers ainda são experimentais. A API pode mudar em versões futuras do Kotlin. Para projetos em produção, avalie cuidadosamente e acompanhe as [notas de release oficiais](https://kotlinlang.org/docs/whatsnew.html).

## Relação com Coroutines e Scope Functions

Se você usa [coroutines](/blog/coroutines-kotlin/), já está familiarizado com o conceito de escopo contextual — `CoroutineScope` funciona de maneira análoga. E as [scope functions](/blog/scope-functions-kotlin/) (let, run, with, apply, also) são primas próximas, operando com receivers implícitos.

Context receivers estendem esse padrão, permitindo que qualquer função declare seus requisitos contextuais de forma tipada e segura.

## Boas práticas

1. **Use com moderação**: não transforme todo parâmetro em context receiver — use apenas para dependências transversais (logging, transações, configuração)
2. **Prefira interfaces**: declare contextos como interfaces, não classes concretas, facilitando testes
3. **Documente os contextos**: como a dependência é implícita, documentar qual contexto é necessário ajuda a manutenibilidade
4. **Acompanhe a evolução**: migre para context parameters quando a funcionalidade estabilizar

## Conclusão

Context Receivers e Context Parameters representam uma evolução natural do sistema de receivers do Kotlin. Eles resolvem o problema de injeção de múltiplos contextos de forma elegante, complementando as [extension functions](/blog/extension-functions-kotlin/) e as [sealed classes](/blog/sealed-classes-kotlin/) no arsenal do desenvolvedor Kotlin.

Embora ainda experimentais, já mostram como o Kotlin continua inovando para tornar o código mais expressivo e seguro. Fique de olho nas próximas versões e comece a experimentar nos seus projetos pessoais.

Para se aprofundar na linguagem, confira nosso [Guia Completo de Kotlin](/guias/guia-completo-kotlin/) e o [Glossário de Kotlin](/glossario/).

Se o conceito de injeção de contexto te interessou, vale explorar como outras linguagens resolvem problemas semelhantes: <a href="https://golang.com.br/blog/" target="_blank" rel="noopener" onclick="umami.track('portfolio-site-click', { destination: 'golang.com.br' })">Go usa o pacote context para propagação de valores entre funções</a>, enquanto <a href="https://rustlang.com.br/blog/" target="_blank" rel="noopener" onclick="umami.track('portfolio-site-click', { destination: 'rustlang.com.br' })">Rust resolve isso com traits e generics no sistema de tipos</a>.
