Kotlin4Noobs

Buscar nas notas

    apply

    Funções de escopo

    let, run, with, apply e also, e quando usar cada uma.

    As funções de escopo executam um bloco de código no contexto de um objeto. Dentro do bloco, o objeto é acessado sem repetir o seu nome, o que deixa o código mais curto e mais fácil de ler. São cinco: let, run, with, apply e also.

    Elas diferem em duas coisas: como o objeto é acessado dentro do bloco (it ou this) e o que a função devolve (o resultado do bloco ou o próprio objeto).

    FunçãoObjeto no blocoDevolveUso comum
    letito resultado do blocoExecutar código só quando o valor não é nulo
    runthiso resultado do blocoConfigurar um objeto e calcular um resultado
    withthiso resultado do blocoAgrupar várias chamadas sobre um objeto
    applythiso próprio objetoConfigurar um objeto
    alsoito próprio objetoEfeitos colaterais, como logs

    let

    let é muito usado com o operador de chamada segura ?., para executar um bloco apenas quando o valor não é nulo:

    fun main() {
        val name: String? = "Kotlin"
    
        val length = name?.let {
            println("O nome é $it")
            it.length
        }
    
        println("Tamanho: $length") // Tamanho: 6
    }

    apply

    apply devolve o próprio objeto, por isso é a escolha natural para configurá-lo logo após criá-lo:

    class Account {
        var owner: String = ""
        var balance: Double = 0.0
    }
    
    fun main() {
        val account = Account().apply {
            owner = "Gustavo"
            balance = 100.0
        }
    
        println("${account.owner}: ${account.balance}") // Gustavo: 100.0
    }

    also

    also também devolve o próprio objeto, mas acessa o objeto como it. Serve para fazer algo a mais com o valor, como registrar um log, sem alterar o fluxo:

    fun main() {
        val numbers = mutableListOf(3, 1, 2)
            .also { println("Lista original: $it") }
            .apply { sort() }
    
        println("Lista ordenada: $numbers") // Lista ordenada: [1, 2, 3]
    }

    run e with

    run e with acessam o objeto como this e devolvem o resultado do bloco. A diferença é que run é chamado sobre o objeto, enquanto with recebe o objeto como argumento:

    fun main() {
        val text = "Kotlin4Noobs"
    
        val summary = text.run { "$this tem $length caracteres" }
    
        val report = with(StringBuilder()) {
            append("Linguagem: ")
            append("Kotlin")
            toString()
        }
    
        println(summary) // Kotlin4Noobs tem 12 caracteres
        println(report) // Linguagem: Kotlin
    }

    Use funções de escopo quando elas deixam o código mais claro. Encadear muitas delas, ou aninhar uma dentro da outra, costuma ter o efeito contrário.