Scope Functions

https://kotlinlang.org/docs/reference/scope-functions.html
Scope Functions

Функции, которые позволяют управлять контекстом объекта и упрощают код, улучшая его читаемость.

TODO

Функция, используемая для пометки мест в коде, где необходимо реализовать логику или завершить задачу. Она позволяет разработчикам оставлять временные заглушки и напоминания о том, что код еще не завершен. Если функция с TODO будет вызвана, она выбросит исключение NotImplementedError.

fun calculate(): Int {
    TODO("Реализовать метод вычисления")
}
let

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

val name: String? = "Kotlin"
name?.let { println("Длина строки: ${it.length}") }  // Выведет длину, если name не null
run

Выполняет блок кода на объекте и возвращает результат последнего выражения в этом блоке. Она позволяет удобно работать с объектами, применяя к ним несколько операций.

val result = StringBuilder().run {
    append("Hello, ")
    append("World!")
    toString()  // Возвращает строку "Hello, World!"
}
with

Используется для выполнения нескольких операций над объектом без его явного указания, и возвращает результат последнего выражения в блоке. with полезен, когда нужно работать с одним объектом последовательно.

val result = with(StringBuilder()) {
    append("Hello, ")
    append("World!")
    toString()  // Возвращает "Hello, World!"
}
apply

Функция-расширение для выполнения операций над объектом в контексте этого объекта, после чего возвращается сам объект. Используется для инициализации или настройки свойств объекта

val person = Person().apply {
    name = "Alice"
    age = 25
}
also

Выполняет блок кода над объектом и возвращает сам объект. Она удобна, когда нужно выполнить дополнительное действие с объектом без изменения его свойств или самого объекта.

val list = mutableListOf(1, 2, 3).also { println("Initial list: $it") }
takeIf

Возвращает объект, если он удовлетворяет заданному условию (в выражении, переданном как аргумент). Если объект не удовлетворяет условию, возвращается null. Это позволяет более лаконично писать код, избегая явных проверок на условия.

val number = 5
val result = number.takeIf { it > 0 } // result = 5, так как 5 больше 0

val anotherNumber = -3
val anotherResult = anotherNumber.takeIf { it > 0 } // anotherResult = null, так как -3 не больше 0
takeUnless

Возвращает объект, если он не удовлетворяет заданному условию (в выражении, переданном как аргумент). Если объект удовлетворяет условию, возвращается null. Это позволяет писать более выразительный и компактный код, особенно при проверках условий.

val number = 5
val result = number.takeUnless { it > 10 } // result = 5, так как 5 не больше 10

val anotherNumber = 15
val anotherResult = anotherNumber.takeUnless { it > 10 } // anotherResult = null, так как 15 больше 10
repeat

Используется для многократного выполнения заданного блока кода определенное количество раз. Это упрощает написание циклов, когда нужно выполнить одни и те же действия несколько раз, улучшая читаемость кода. Позволяет легко создавать циклы без явного использования for или while.

repeat(5) { index ->
    println("Итерация $index")
}
this

Ссылается на объект, на котором вызывается функция. Это полезно, когда вам нужно получить доступ к свойствам или методам объекта внутри лямбда-выражения. Используется в run, with, и apply: В этих функциях this ссылается на объект, который передан в качестве receiver.

data class Person(
		var name: String,
		var age: Int
)

val person = Person("Alice", 30).apply {
    this.age += 1 // Используем this для изменения свойства age
}
it

Является неявной ссылкой на объект, переданный в лямбда-выражение, когда функция принимает один параметр. Используется в let, also: В этих функциях it ссылается на объект, переданный в качестве аргумента.

val length = "Hello".let {
    it.length // Используем it для получения длины строки
}
Вопросы на собесе (4)
  1. Какие есть Scope-функции?

    let run with apply also

  1. let, run, with, apply, also что это за ключевые слова?

    Это функции области видимости (scope functions) в Kotlin, которые помогают выполнять действия над объектами или изменять их состояние. Они отличаются контекстом вызова и тем, как объект доступен внутри лямбды (через this или it).

  1. Возвращает ли run значение?

    Да, функция run возвращает результат последнего выражения внутри своего блока.

  1. Для чего нужны такое scope-функции в Kotlin?

    Для упрощения работы с объектами, повышения читаемости кода и уменьшения дублирования. Позволяют выполнять операции в контексте объекта, упрощая доступ к его свойствам и методам, а также могут изменять объект или возвращать результаты.