Kotlin let, run, also, apply, with

В этом учебном пособии мы будем реализовывать некоторые из важных стандартных функций библиотеки, доступных в Kotlin. kotlin-stdlib предоставляет нам полезные функции высшего порядка, реализующие идиоматические шаблоны. Мы увидим, как они делают программирование на Kotlin проще и быстрее. Функции, которые мы собираемся обсудить ниже, включают:

  • let
  • run
  • also
  • apply
  • with

Kotlin let

let принимает объект, на который он вызывается, в качестве параметра и возвращает результат лямбда-выражения. Kotlin let – это функция области видимости, в которой переменные, объявленные внутри выражения, не могут быть использованы вне его. Приведен пример демонстрации функции let Kotlin ниже.

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

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

it ключевое слово содержит копию свойства внутри let. Последнее значение из let возвращается в качестве аргумента, как показано ниже.

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

Цепочка функций let

var a = 1
var b= 2

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

Как видите, мы объявили локальную переменную “i” внутри второй функции let. Установка последнего оператора функции let в i возвращает свойство во внешнее свойство a.

Вложенная let

Мы можем установить выражение let внутри другого выражения let, как показано ниже.

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

//Prints
// Внутреннее - Anupam, внешнее - Anupam

Для вложенной let мы не можем использовать ключевое слово it. Нам нужно назначить явные имена it в обе функции let. Только самая внешняя let возвращает значение, как показано ниже.

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 для проверки на null

Кроме того, let полезен для проверки Nullable свойств, как показано ниже.

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

Код внутри выражения let выполняется только в том случае, если свойство не равно null. Таким образом, let также избавляет нас от проверки на null с использованием if else!

Запуск Kotlin

Функция Kotlin run – еще одна интересная функция. В следующем примере показаны её варианты использования.

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

Выражение run Kotlin может изменить внешнее свойство. Поэтому в приведенном выше коде мы переопределили его для локальной области видимости.

  • Аналогично функции let, функция run также возвращает последнее выражение.
  • В отличие от let, функция run не поддерживает ключевое слово it.

let и run

Давайте объединим функции let и run вместе.

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 был равен null. Установка значения по умолчанию: 
//Kotlin

Kotlin также

Как говорит название, выражение also выполняет дополнительную обработку объекта, для которого оно вызвано. В отличие от let, оно возвращает исходный объект вместо каких-либо новых данных возвращения. Поэтому возвращаемые данные всегда имеют тот же тип. Как и let, also также использует it.

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

Котлин let против also

Следующий фрагмент кода приводит отличный пример различия между let и also.

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)

В приведенном выше коде мы использовали Data-классы. Выражение also возвращает объект класса данных, тогда как выражение let возвращает ничего (Unit), поскольку мы явно ничего не указали.

Котлин apply

Apply в Котлин является расширением для типа. Он выполняется на ссылке объекта (также известной как приемник) в выражении и возвращает ссылку на объект при завершении.

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

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

apply против 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)

Примечание: В apply использование it не допускается. Если имя свойства data-класса уникально в функции, можно опустить this. Мы должны использовать also только тогда, когда мы не хотим затенять this.

Котлин с

Как и apply, with используется для изменения свойств экземпляра без необходимости вызывать оператор точки каждый раз для ссылки.

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

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

Опять же with аналогичен apply, за исключением нескольких различий.

Применение vs with в Kotlin

  • with выполняется без объекта (получателя), в то время как apply требуется объект.
  • apply работает с ссылкой на объект, в то время как with просто передает его в качестве аргумента.
  • Последнее выражение функции with возвращает результат.
var xyz = with(person)
    {
        name = "No Name"
        tutorial = "Kotlin tutorials"
        val xyz = "End of tutorial"
        xyz
    }
    println(xyz) //End of tutorial

Это все для стандартных функций Kotlin по изменению переменных или модификации объектов внутри функции.

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