Rafael

Engenheiro de Software

Olá, Eu sou Rafael. Estou construindo coisas para a web e mobile.

Um desenvolvedor dedicado a criar experiências digitais de alto desempenho, acessíveis e limpas. Eu me especializo em transformar problemas complexos em soluções de engenharia elegantes.

Funções de escopo em Kotlin

A biblioteca padrão do Kotlin contém diversas funções cuja única finalidade é executar um bloco de código dentro do contexto de um objeto. Quando você chama uma dessas funções em um objeto com uma expressão lambda fornecida, cria-se um escopo temporário. Nesse escopo, você pode acessar o objeto sem o seu nome. Essas funções são chamadas de funções de escopo.

Existem cinco delas:

  • `let`
  • `run`
  • `with`
  • `apply`
  • `also`

Basicamente, todas essas funções executam a mesma ação: executar um bloco de código em um objeto. O que as diferencia é como esse objeto se torna disponível dentro do bloco e qual o resultado da expressão como um todo.

Um exemplo típico de como usar uma função de escopo:

KOTLIN
Person("Alice", 20, "Amsterdam").let {
    println(it)
    it.moveTo("London")
    it.incrementAge()
    println(it)
}

Se você escrever o mesmo sem o “let”, terá que introduzir uma nova variável e repetir o nome dela sempre que a usar.

KOTLIN
val alice = Person("Alice", 20, "Amsterdam")
println(alice)
alice.moveTo("London")
alice.incrementAge()
println(alice)

Por que usar funções de escopo?

  • Código legível: Elas tornam seu código mais expressivo e conciso.
  • Escopos temporários: Permitem realizar operações em objetos dentro de um escopo restrito.
  • Evitam verificações de nulo: Reduzem o código repetitivo para garantir a segurança contra nulos.
  • Encadeamento de operações: Simplificam operações como inicializar objetos, configurar propriedades ou aplicar transformações.

Como as funções de escopo diferem?

Cada função de escopo possui:

  • Um objeto de contexto: o objeto sobre o qual ela opera.
  • Um valor de retorno: o próprio objeto ou o resultado do bloco.
  • Uma referência ao objeto de contexto: pode ser acessada como `this` ou `it`.

As funções de escopo não introduzem novas capacidades técnicas, mas podem tornar seu código mais conciso e legível.

Devido às muitas semelhanças entre as funções de escopo, escolher a mais adequada para o seu caso de uso pode ser complicado. A escolha depende principalmente da sua intenção e da consistência de uso no seu projeto. Abaixo, fornecemos descrições detalhadas das diferenças entre as funções de escopo e suas convenções.

Para ajudar você a escolher a função de escopo mais adequada à sua necessidade, fornecemos esta tabela que resume as principais diferenças entre elas.

Seleção de função

FunçãoReferência do objetoValor de retornoÉ uma função de extensão
letitResultado lambdaSim
runthisResultado lambdaSim
runResultado lambdaNão: chamado sem o objeto de contexto
withthisResultado lambdaNão: recebe o objeto de contexto como argumento.
applythisObjeto de contextoSim
alsoitObjeto de contextoSim

let

A função let é usada para realizar operações em um objeto anulável e retornar um resultado. Ela é frequentemente usada para verificar valores nulos ou encadear transformações.

Exemplo: Verificando e Transformando um Objeto Anulável

KOTLIN
val name: String? = "Kotlin"
val length = name?.let {
    println("Name: $it")
    it.length
}
println(length) // Output: 6

Quando usar let:

  • Para evitar exceções de ponteiro nulo.
  • Quando você precisa transformar o objeto e retornar um resultado.

apply

A função apply é usada para configurar um objeto. Ela retorna o próprio objeto, sendo ideal para inicializar propriedades.

Exemplo: Imagine que você está criando um objeto de interface do usuário e precisa definir várias propriedades.

KOTLIN
val button = Button(context).apply {
    text = "Click Me"
    isEnabled = true
    setOnClickListener { println("Button clicked!") }
}

// Usage
println(button.text) // Outputs: Click Me

Quando usar apply:

  • Quando você precisa inicializar ou modificar um objeto.

run

    A função run combina as funcionalidades de let e apply. Ela executa um bloco de código e retorna o resultado.

    Exemplo: Realizar operações e retornar um resultado

    KOTLIN
    val user = User("Anand", 25)
    val isAdult = user.run {
        println("Name: $name, Age: $age")
        age >= 18
    }
    println(isAdult) // Output: true

    Quando usar run:

    • Quando você precisa realizar operações em um objeto e retornar um resultado.

    also

    A função also é usada quando você deseja executar ações adicionais sem modificar o objeto.

    Exemplo: Ações de registro

    KOTLIN
    val numbers = mutableListOf(1, 2, 3).also {
        println("Original List: $it")
        it.add(4)
        it.remove(1)
    }
    println(numbers) // Output: [2, 3, 4]

    Quando usar also:

    • Quando você deseja executar efeitos colaterais (por exemplo, registro ou depuração).

    with

    A função with é usada para operar diretamente em um objeto. Ela é frequentemente usada para agrupar operações em um objeto.

    Exemplo: Imagine que você tenha um objeto de configuração que requer várias configurações.

    KOTLIN
    fun configureSettings(): Settings {
        val settings = Settings()
        with(settings) {
            enableDarkMode()
            setLanguage("en")
            setRegion("US")
        }
        return settings
    }
    
    // Usage
    val settings = configureSettings()
    println(settings.language) // Outputs: en

    Quando usar with:

    • Quando você precisa realizar várias operações em um único objeto.

    Qual a diferença entre it e this em funções de escopo?

    • it: Usado quando o objeto é acessado por um nome implícito em funções de escopo como let e also.
    • this: Usado quando o objeto é referenciado como um receptor em funções de escopo como apply, run e with.

    0 comentários

    Deixe seu comentário