---
title: "Scope Functions em Kotlin: O que São e Como Usar | Kotlin Brasil"
url: "https://kotlin.dev.br/glossario/scope/"
markdown_url: "https://kotlin.dev.br/glossario/scope.MD"
description: "Conheça as Scope Functions em Kotlin: let, run, with, apply e also. Entenda quando e como usar cada uma no seu código."
date: "2026-02-07"
author: "Karina Melo"
---

# Scope Functions em Kotlin: O que São e Como Usar | Kotlin Brasil

Conheça as Scope Functions em Kotlin: let, run, with, apply e also. Entenda quando e como usar cada uma no seu código.


## O que são Scope Functions em Kotlin?

Scope Functions são cinco funções da biblioteca padrão do Kotlin — `let`, `run`, `with`, `apply` e `also` — que permitem executar um bloco de código **no contexto de um objeto**. Elas deixam o código mais conciso e expressivo.

A diferença entre elas está em como o objeto é referenciado dentro do bloco (`this` ou `it`) e no que cada uma retorna.

### Resumo rápido

| Função | Referência | Retorno |
|---|---|---|
| `let` | `it` | Resultado do lambda |
| `run` | `this` | Resultado do lambda |
| `with` | `this` | Resultado do lambda |
| `apply` | `this` | O próprio objeto |
| `also` | `it` | O próprio objeto |

### `let` — transformações e null safety

```kotlin
val nome: String? = "Kotlin Brasil"
nome?.let {
    println("O nome tem ${it.length} caracteres")
}
```

Perfeito pra trabalhar com valores nullable de forma segura.

### `apply` — configurar objetos

```kotlin
data class Servidor(var host: String = "", var porta: Int = 0, var protocolo: String = "")

val servidor = Servidor().apply {
    host = "api.kotlin.dev.br"
    porta = 443
    protocolo = "HTTPS"
}
println(servidor)
```

O `apply` retorna o próprio objeto, ideal pra configurar e já usar em seguida.

### `also` — ações laterais

```kotlin
val numeros = mutableListOf(1, 2, 3)
    .also { println("Lista original: $it") }
    .also { it.add(4) }

println(numeros) // [1, 2, 3, 4]
```

Bom pra logging e debug sem quebrar a cadeia de chamadas.

### `run` — calcular resultado

```kotlin
val resultado = "Kotlin".run {
    println("Processando: $this")
    length * 2
}
println(resultado) // 12
```

### `with` — operar sobre um objeto

```kotlin
val sb = StringBuilder()
val texto = with(sb) {
    append("Olá, ")
    append("mundo!")
    toString()
}
println(texto) // Olá, mundo!
```

### Combinando scope functions

Na prática, você frequentemente combina scope functions para criar código fluente e expressivo. Veja um exemplo de configuração de uma requisição HTTP:

```kotlin
data class Requisicao(
    var url: String = "",
    var metodo: String = "GET",
    var headers: MutableMap<String, String> = mutableMapOf(),
    var corpo: String? = null
)

fun criarRequisicao(): Requisicao {
    return Requisicao().apply {
        url = "https://api.kotlin.dev.br/usuarios"
        metodo = "POST"
        headers["Content-Type"] = "application/json"
        headers["Authorization"] = "Bearer token123"
        corpo = """{"nome": "Karina"}"""
    }.also {
        println("Requisição criada: ${it.metodo} ${it.url}")
    }
}
```

### `run` sem objeto — executando blocos

O `run` também pode ser usado sem um objeto receptor, funcionando como um bloco de código que retorna um valor:

```kotlin
val resultado = run {
    val a = 10
    val b = 20
    val c = 30
    a + b + c
}
println(resultado) // 60
```

Isso é útil quando você precisa calcular um valor complexo em uma variável `val`, criando um escopo isolado para variáveis temporárias.

### `let` para encadeamento de transformações

O `let` brilha quando você precisa transformar um valor em cadeia:

```kotlin
fun processarEntrada(entrada: String?): String {
    return entrada
        ?.let { it.trim() }
        ?.let { it.lowercase() }
        ?.let { it.replace(" ", "_") }
        ?.let { "usuario_$it" }
        ?: "usuario_anonimo"
}

fun main() {
    println(processarEntrada("  Kotlin Brasil  ")) // usuario_kotlin_brasil
    println(processarEntrada(null))                  // usuario_anonimo
}
```

### Qual usar?

Na dúvida: `apply` pra configurar, `let` pra null safety, `also` pra ações laterais, `run` pra calcular algo e `with` quando já tem o objeto em mãos.

### Casos de Uso no Mundo Real

- **Configuração de objetos complexos**: usar `apply` para configurar ViewModels, clientes HTTP, builders de notificação e outros objetos com múltiplas propriedades no Android e backend.
- **Null safety em respostas de API**: usar `let` combinado com `?.` para processar dados que podem ser nulos vindos de APIs REST ou banco de dados, evitando verificações manuais de null.
- **Logging e debug em pipelines**: inserir `also` no meio de cadeias de chamadas para imprimir valores intermediários sem alterar o fluxo de dados, facilitando a depuração.
- **Inicialização de recursos com `run`**: usar `run` para criar e configurar recursos como conexões de banco de dados, onde o resultado da configuração é o valor retornado.

### Boas Práticas

- Não aninhe scope functions. `objeto.let { it.apply { also { } } }` é ilegível. Limite-se a um nível de profundidade.
- Use `apply` para configuração e `also` para efeitos colaterais. Embora ambos retornem o próprio objeto, a distinção semântica mantém o código claro.
- Prefira `let` com nome explícito para lambdas longas: `valor?.let { usuário -> ... }` é mais legível que `valor?.let { it.nome; it.email; ... }` quando o bloco é grande.
- Use `with` apenas quando o objeto não é nullable. Como `with` não é uma função de extensão, ele não funciona com o operador `?.`.
- Mantenha blocos de scope functions curtos — entre 3 e 7 linhas. Se o bloco crescer muito, extraia para uma função separada.

### Erros Comuns

- **Aninhar scope functions excessivamente**: `a.let { it.run { this.apply { } } }` cria código impossível de entender. Se precisa de mais de uma scope function, quebre em etapas.
- **Confundir `this` e `it`**: `apply` e `run` usam `this` (receptor implícito); `let` e `also` usam `it` (parâmetro explícito). Usar o errado gera confusão e erros de compilação.
- **Usar `let` sem necessidade**: `valor.let { println(it) }` não é melhor que `println(valor)`. Use `let` quando há uma razão real, como null safety ou transformação.
- **Ignorar o retorno**: `apply` e `also` retornam o objeto; `let`, `run` e `with` retornam o resultado do lambda. Confundir isso leva a bugs sutis, especialmente em cadeias de chamadas.
- **Usar `with` em objetos nullable**: como `with` não é uma extensão, `with(objetoNullable)` compila mas pode dar `NullPointerException`. Para nullable, prefira `objetoNullable?.run { }`.

### Perguntas Frequentes

**Qual a diferença entre `let` e `run`?** Ambos retornam o resultado do lambda. A diferença é que `let` referência o objeto como `it` (parâmetro), enquanto `run` referência como `this` (receptor). Use `let` quando precisar de um nome explícito para o objeto ou para null safety; use `run` quando quiser acessar propriedades e métodos diretamente.

**Posso substituir todas as scope functions por `if/else` e variáveis temporárias?** Sim, scope functions são açúcar sintático. Mas elas tornam o código mais idiomático e expressivo. A comunidade Kotlin espera ver scope functions usadas nos contextos apropriados.

**Scope functions afetam a performance?** Na prática, não. As scope functions `let`, `run`, `with`, `apply` e `also` são todas `inline`, ou seja, não criam objetos lambda em tempo de execução. O compilador insere o código diretamente no ponto de chamada.

**Quando usar `with` em vez de `run`?** Use `with` quando já tem o objeto em uma variável e quer operar sobre ele sem encadear. Use `run` quando quer encadear a chamada com `?.` (null safety) ou quando o objeto é resultado de outra expressão.

### Termos Relacionados

- [Lambda](/glossario/lambda) — expressões lambda que formam o bloco de código das scope functions
- [Extension Function](/glossario/extension-function) — `let`, `run`, `apply` e `also` são funções de extensão
- [Nullable](/glossario/nullable) — scope functions como `let` são fundamentais para null safety
- [Inline Function](/glossario/inline) — scope functions são inline, sem overhead de runtime
- [Higher-Order Function](/glossario/higher-order-function) — scope functions são funções de ordem superior
