Лямбды — функции как значения

Знакомимся с лямбдами — короткими безымянными функциями.

Лямбда-выражение — функция без имени, записанная прямо в коде в фигурных скобках, которую можно передать как значение.

В Kotlin функции — это полноценные значения: их можно хранить в переменных и передавать в другие функции. Чаще всего это делают через лямбды — компактную форму записи функции.

Синтаксис лямбды

Лямбда заключается в фигурные скобки. Параметры идут до стрелки ->, тело — после.

fun main() {
    val sum = { a: Int, b: Int -> a + b }
    println(sum(2, 3))

    val square = { x: Int -> x * x }
    println(square(5))
}

Вывод:

5
25

Неявный параметр it

Если у лямбды ровно один параметр, его можно не объявлять — он доступен под именем it. Это делает короткие лямбды совсем компактными.

fun main() {
    val numbers = listOf(1, 2, 3, 4)
    val doubled = numbers.map { it * 2 }
    println(doubled)
}

Вывод:

[2, 4, 6, 8]

Лямбда как последний аргумент

Если лямбда — последний аргумент функции, её можно вынести за круглые скобки. Это фирменный «trailing lambda»-синтаксис Kotlin, делающий вызовы похожими на встроенные конструкции.

fun main() {
    val nums = listOf(5, 1, 4, 2)
    // обе записи эквивалентны
    val a = nums.filter({ it > 2 })
    val b = nums.filter { it > 2 }
    println(b)
}

Вывод:

[5, 4]

Как работает под капотом

Лямбда имеет тип функции, например (Int) -> Int — «принимает Int, возвращает Int». Это обычный тип, поэтому лямбду можно хранить в переменной такого типа. Возвращаемое значение лямбды — это значение её последнего выражения; отдельный return внутри лямбды писать не нужно (и обычный return там ведёт себя особым образом).

Частые ошибки

  • Писать return внутри лямбды. Результат — это последнее выражение; явный return здесь не нужен.
  • Использовать it при двух параметрах. it доступен только для лямбды с одним параметром.
  • Бояться trailing lambda. Запись list.filter { it > 0 } — это та же лямбда, просто вынесенная за скобки.

Итог

  • Лямбда — безымянная функция в фигурных скобках с параметрами до ->.
  • Для одного параметра используется неявное имя it.
  • Лямбду можно хранить в переменной и передавать в функции.
  • Последнюю лямбду-аргумент выносят за круглые скобки.
Проверьте себя
1. Как обратиться к единственному параметру лямбды, не объявляя его?
Athis
Bit
Carg
D_
2. Чему эквивалентна запись nums.filter { it > 2 }?
Anums.filter() { it > 2 }, но с ошибкой
Bnums.filter({ it > 2 }) — лямбда вынесена за скобки
CФильтрации по индексу
DСортировке списка
3. Что является результатом лямбды { a: Int, b: Int -> a + b }?
Anull
BЗначение последнего выражения, то есть a + b
CВсегда 0
DНужен явный return