Kotlin let, run, also, apply, with

Neste tutorial, estaremos implementando algumas das importantes funções da biblioteca padrão disponíveis no Kotlin. O kotlin-stdlib nos fornece úteis funções de ordem superior implementando padrões idiomáticos. Veremos como elas tornam a programação em Kotlin tão mais fácil e rápida. As funções que vamos discutir abaixo são:

  • let
  • run
  • also
  • apply
  • with

Kotlin let

let recebe o objeto sobre o qual é invocado como parâmetro e retorna o resultado da expressão lambda. O Kotlin let é uma função de escopo na qual as variáveis declaradas dentro da expressão não podem ser usadas fora dela. Um exemplo demonstrando a função let do Kotlin é dado abaixo.

fun main(args: Array) {
    var str = "Hello World"
    str.let { println("$it!!") }
    println(str)

}
//Prints
//Hello World!!
//Hello World

it contém a cópia da propriedade dentro do let. O último valor do let é retornado como argumento, conforme mostrado abaixo.

var strLength = str.let { "$it function".length }
println("strLength is $strLength") //prints strLength is 25

Encadeando funções let

var a = 1
var b= 2

a = a.let { it + 2 }.let { val i = it + b
        i}
println(a) //5

Como você pode ver, declaramos uma variável local “i” dentro da segunda função let. Definir o último comando da função let como i retorna a propriedade para a propriedade externa a.

Aninhando let

Podemos definir uma expressão let dentro de outra expressão let como mostrado abaixo.

var x = "Anupam"
x.let { outer -> outer.let { inner -> print("Inner is $inner and outer is $outer") } }

//Prints
//Inner é Anupam e outer é Anupam

Para let aninhado, não podemos usar a palavra-chave it. Precisamos atribuir nomes explícitos a it em ambas as funções let. Apenas o let mais externo retorna o valor como mostrado abaixo.

var x = "Anupam"
    x = x.let { outer ->
        outer.let { inner ->
            println("Inner is $inner and outer is $outer")
            "Kotlin Tutorials Inner let"
        }
        "Kotlin Tutorials Outer let" 
    }
    println(x) //prints Kotlin Tutorials Outer let

let para verificações nulas

Além disso, let é útil para verificar propriedades nulas, como mostrado abaixo.

var name : String? = "Kotlin let null check"
name?.let { println(it) } //prints Kotlin let null check
name = null
name?.let { println(it) } //nothing happens

O código dentro da expressão let é executado apenas quando a propriedade não é nula. Assim, o let nos poupa do verificador de nulos do if else também!

Executar Kotlin

O run do Kotlin é outra função interessante. O exemplo a seguir demonstra seus casos de uso.

var tutorial = "This is Kotlin Tutorial"
    println(tutorial) //This is Kotlin Tutorial
    tutorial = run {
        val tutorial = "This is run function"
        tutorial
    }
    println(tutorial) //This is run function

A expressão run do Kotlin pode alterar a propriedade externa. Portanto, no código acima, a definimos novamente para o escopo local.

  • Semelhante à função let, a função run também retorna a última instrução.
  • Ao contrário de let, a função run não suporta a palavra-chave it.

let e run

Vamos combinar as funções let e run juntas.

var p : String? = null
    p?.let { println("p is $p") } ?: run { println("p was null. Setting default value to: ")
        p = "Kotlin"}

    println(p)
//Prints
//p estava nulo. Definindo valor padrão para: 
//Kotlin

O Kotlin também

Como o nome sugere, as expressões também realizam algum processamento adicional no objeto no qual foram invocadas. Ao contrário de let, elas retornam o objeto original em vez de novos dados de retorno. Portanto, os dados de retorno sempre têm o mesmo tipo. Assim como let, também também usa it.

var m = 1
m = m.also { it + 1 }.also { it + 1 }
println(m) //prints 1 

Kotlin let vs also

O trecho de código a seguir mostra um ótimo exemplo para diferenciar entre let e também.

data class Person(var name: String, var tutorial : String)
var person = Person("Anupam", "Kotlin")

var l = person.let { it.tutorial = "Android" }
var al = person.also { it.tutorial = "Android" }
    
println(l)
println(al)
println(person)

No código acima, usamos classes de dados. A expressão also retorna o objeto da classe de dados, enquanto a expressão let não retorna nada (Unit) pois não especificamos nada explicitamente.

Kotlin apply

O apply do Kotlin é uma função de extensão em um tipo. Ele é executado no objeto de referência (também conhecido como receptor) na expressão e retorna a referência do objeto ao completar.

data class Person(var name: String, var tutorial : String)
var person = Person("Anupam", "Kotlin")

person.apply { this.tutorial = "Swift" }
println(person)

apply vs also

data class Person(var n: String, var t : String)
var person = Person("Anupam", "Kotlin")

person.apply { t = "Swift" }
println(person)

person.also { it.t = "Kotlin" }
println(person)

Observação: No apply, it não é permitido. Se o nome da propriedade da classe de dados for único na função, você pode omitir this. Devemos usar também apenas quando não queremos obscurecer this.

Kotlin com

Assim como apply, with é usado para alterar propriedades da instância sem a necessidade de chamar o operador ponto sobre a referência toda vez.

data class Person(var name: String, var tutorial : String)
var person = Person("Anupam", "Kotlin")

with(person)
    {
        name = "No Name"
        tutorial = "Kotlin tutorials"
    }

Novamente, with é semelhante ao apply, exceto por algumas diferenças.

Kotlin apply vs with

  • O with é executado sem um objeto (receptor), enquanto o apply precisa de um.
  • O apply é executado na referência do objeto, enquanto o with apenas a passa como argumento.
  • A última expressão da função with retorna um resultado.
var xyz = with(person)
    {
        name = "No Name"
        tutorial = "Kotlin tutorials"
        val xyz = "End of tutorial"
        xyz
    }
    println(xyz) //End of tutorial

Isso é tudo para as funções padrão do Kotlin para alterar variáveis ou modificar objetos dentro da função.

Source:
https://www.digitalocean.com/community/tutorials/kotlin-let-run-also-apply-with