Лямбда-выражение состоит из параметров, лямбда-операции ->
и тела лямбда-выражения. Например:
(ПервыйПараметр, ВторойПараметр) -> ПервыйПараметр * ВторойПараметр
Так в программном коде может выглядеть значение функционального типа при записи в переменную:
пер c: (Число)->Число = x -> x * x
а так — при объявлении и вызове метода:
Сравнить(2, 3, (x, y) -> x == y)
метод Сравнить(x: Число, y: Число, z: (Число, Число)->Булево)
;
Лямбда-выражение — функция анонимная, то есть для нее не требуется указывать имя, и в системе она не привязана к идентификатору. Анонимность и компактность лямбда-выражений позволяют записывать весь метод целиком (и параметры, и результат) непосредственно в список параметров другого метода или в тело другого метода как возвращаемое значение.
Синтаксис
Краткая форма
(параметр-1, ..., параметр-N) -> выражение
- Несколько параметров с типом:
(параметр-1: тип-1, ..., параметр-N: тип-N) -> выражение
Примеры:
x -> x + 1
(x: Число) -> x + 1
(x, y) -> x + y
(x: Число, y: Число) -> x + y
Полная форма
Используется ключевое слово метод
.
Тело лямбда-выражения может быть многострочным и заканчивается символом ;
.
метод(параметр) -> тело лямбда-выражения;
метод(параметр-1, ..., параметр-N) -> тело лямбда-выражения;
- Несколько параметров с типом:
метод(параметр-1: тип-1, ..., параметр-N: тип-N) -> тело лямбда-выражения;
Примеры:
метод(x) ->
возврат x + 1
;
метод(x: Число) ->
возврат x + 1
;
метод(x, y) ->
возврат x + y
;
метод(x: Число, y: Число) ->
возврат x + y
;
Захват контекста
В момент создания лямбда-выражения (когда исполнение кода доходит до места, где описано лямбда-выражение) захватываются значения используемых в лямбда-выражении локальных переменных внешнего метода.
Привязка лямбда-выражения к переменным внешнего метода называется замыканием, а сами эти нелокальные переменные называются свободными. Таким образом, лямбда-выражение позволяет вложить один метод в другой, а замыкание позволяет связать метод с внешней переменной. Захват контекста предполагает определенные ограничения:
-
Запрещается использовать в параметрах лямбда-выражения переменные, объявленные вне тела лямбда-выражения (переменная Сообщение
определена раньше):
метод Скрипт(Имя: Строка): Строка
пер Сообщение = "Привет, "
пер Печать = (Сообщение: Строка, Имя: Строка) -> Сообщение + Имя + "!"
возврат Печать()
;
-
Запрещается объявлять или изменять в теле лямбда-выражения переменные, объявленные вне тела лямбда-выражения (переменная Сообщение
определена раньше):
метод Скрипт(Имя: Строка): Строка
пер Сообщение = "Привет, "
пер Печать = метод() ->
пер Сообщение = "Добро пожаловать, "
возврат Сообщение + Имя + "!"
;
возврат Печать()
;
-
Запрещается изменять переменные после их использования в лямбда-выражении (разрешается до):
метод Скрипт(Имя: Строка): Строка
пер Печать = метод() ->
возврат Сообщение + Имя + "!"
пер Сообщение = "Привет, "
;
возврат Печать()
;
или
метод Скрипт(Имя: Строка): Строка
пер Печать = метод() ->
возврат Сообщение + Имя + "!"
;
пер Сообщение = "Привет, "
возврат Печать()
;
-
В циклах:
метод Скрипт()
пер Сообщение = "Привет, "
пер Имя = ""
пер СписокИмен = ПолучитьСписокИмен()
пер Печать = метод() ->
пер Приветствие: Массив<Строка>
для Имя из СписокИмен
Приветствие.Добавить(Сообщение + Имя + "!")
;
возврат Приветствие
;
пер Результат = Печать()
;
или
метод Тест()
пер п = 4
для i = 1 по 5
п += i
знч Лямбда = () -> п
;
;
Отладка и стек исключений
В отладке и стеке исключений лямбда-выражения выглядят как обычные методы.
Имена методов лямбда-выражений формируются как:
имя_метода_с_лямбда_выражением$имя_лямбда_выражения$имя_вложенного_лямбда_выражения$...
где:
имя_лямбда_выражения
= <мета-имя><номер_лямбда_выражения>
мета-имя
- имя параметра на текущем языке компиляции, в качестве которого передано лямбда-выражение
- иначе — отсутствует
Пример:
метод тес т()
знч л0 = метод() ->
знч л0л0 = () -> 5
;
знч л1 = метод() ->
знч л1л0 = () -> 5
;
;
метод тест2()
знч л0 = лямбда1(x->x)
;
метод лямбда1(лямбда2: (Число)->Число): (Число)->Число
возврат лямбда2
;
Примеры
См. также