Анонимная функция в программировании — особый вид функций, которые объявляются в месте использования и не получают уникального идентификатора для доступа к ним. Поддерживаются во многих языках программирования.
Обычно при создании анонимные функции либо вызываются напрямую, либо ссылка на функцию присваивается переменной, с помощью которой затем можно косвенно вызывать данную функцию. Но в последнем случае анонимная функция получает имя и уже перестаёт быть анонимной. Если анонимная функция ссылается на переменные, не содержащиеся в её теле (захват), то такая функция называется замыканием. Лямбда-выражение — типичная для многих языков синтаксическая конструкция для определения анонимной функции.
Синтаксис
Синтаксис записи анонимных функций для различных языков программирования в большинстве случаев сильно различается.
Язык
|
Пример записи сложения
|
AS3
|
function(x:int, y:int):int{return x + y;}
|
C#
|
|
C++
|
Введены в C++11. Обязательно должны присутствовать захват и тело. Полная форма[1]:
[захват](параметры)mutable исключения атрибуты->возвращаемый_тип{тело}
Пример[2]:
[](int x, int y){ return x + y; }
В C++14 была добавлена возможность использовать лямбда-функции с auto [3]:
auto lambda = [](auto x, auto y) {return x + y;};
Анонимная функция может захватывать как отдельные переменные, например:int a; auto f = [a](){return a;}
так и все внешние переменные: по ссылке [&] или с помощью копии [=]. Также можно комбинировать эти подходы: например, все переменные захватить по ссылке, а определённые параметры по копии. Чтобы иметь возможность модифицировать переменные, захваченные по значению, нужно указать ключевое слово mutable при объявлении функции. В C++14 добавлена возможность инициализации переменных лямбды в захвате. Например: [a = std::string{}](){return a;}
|
CoffeeScript
|
|
D
|
// короткая форма записи с автовыводом типов
auto a = ((x, y) => x + y)(2, 3);
// длинная форма записи (блок с фигурными скобками) с автовыводом типов
auto aa = (x, y) { return x + y; }(2, 3);
// автоопределение компилятором типа анонимной функции: функция или делегат
auto b = (int x, int y) => x + y;
auto bb = (int x, int y) { return x + y; };
// функции не имеют доступа к внешним переменным
auto c = function(int x, int y) => x + y;
auto cc = function(int x, int y) { return x + y; };
// делегаты имеют доступ к внешним переменным
auto d = delegate(int x, int y) => x + y;
auto dd = delegate(int x, int y) { return x + y; };
// делегат, принимающий переменную типа int и возвращающий значение типа double
auto f = delegate double(int x) { return 5.0 / x; };
|
Delphi (c 2009 версии)
|
function(x, y: integer): integer
begin
result := x+y;
end;
|
Erlang
|
|
GNU Octave
|
|
Go
|
Z := func() int {
return X + Y
}()
|
Groovy
|
|
Haskell
|
|
Java (с версии 8)
|
// with no parameter
() -> System.out.println("Hello, world.");
// with a single parameter (This example is an identity function).
a -> a
//with a single expression
(a, b) -> a + b
// with explicit type information
(Long id, String name) -> "id: " + id + ", name:" + name
// with a code block
(a, b) -> {return a + b;}
// with multiple statements in the lambda body. It requires a code block.
// This example also includes a nested lambda expression as well as a closure.
(id, newPrice) -> {
Optional<Product> mayBeProduct = findProduct(id);
mayBeProduct.ifPresent(product -> product.setPrice(newPrice));
return mayBeProduct.get();
}
|
JavaScript
|
Стрелочная функция (arrow function expression) всегда объявляется без имени. Стрелочные функции добавлены в стандарт ECMAScript 6 (также известном как ECMAScript 2015)[4].
// Стрелочная функция. ES6+ (ES2015+)
(x, y) => x + y;
Объявление функции через выражение функции (function expression) без указания имени. Впервые такой способ описан в спецификации стандарта ECMAScript 3[5][6].
// Выражение функции. ES3+
function(x, y) { return x + y }
Динамическое создание функции конструктором объекта Function (Function constructor) всегда объявляется без имени. Более короткая запись динамического создания функции — вызов функции Function, который автоматически вызывает конструктор Function с теми же параметрами. Эти способы создания функций существуют с самых ранних спецификаций, начиная с ECMAScript первой редакции[7][8].
// Динамическое создание функции конструктором Function. ES1+
new Function('x', 'y', 'return x + y')
// Более короткая запись. ES1+
Function('x', 'y', 'return x + y')
|
Lua
|
function(x,y) return x+y end
|
Maple
|
|
Mathematica
|
или
или
[9][10]
|
MATLAB
|
|
Maxima
|
|
Nim
|
proc(x,y: int): int = x*y
|
PascalABC.NET
|
|
Perl
|
sub { return $_[0] + $_[1] }
[11]
|
PHP
|
// PHP 7.4+
fn($x, $y) => $x + $y;
Стрелочные функции (Arrow Functions) добавлены в PHP 7.4[12].
// PHP 5.3+
function($x, $y) use ($a, &$b) { return $x + $y; }
Здесь $a, $b — захваченные переменные, при этом переменная $b ещё и замкнутая[13][14].
// PHP 4.0.1+
create_function('$x, $y', 'return $x + $y;')
Создание анонимной функции с помощью функции create_function[15]. Такой способ объявлен устаревшим, начиная с PHP 7.2.0.
|
PowerShell
|
{ param($x, $y) $x + $y }
[16]
|
Python
|
[17]
|
R
|
|
Ruby
|
[18]
|
Rust
|
|
Scala
|
Без указания контекста надо указывать тип переменных:
(x: Int, y: Int) => x + y
Но в местах, где тип может быть выведен, можно использовать сокращенные формы:
(1 to 100) reduce ((a, b) => a+b)
Или ещё короче, с использованием автоподстановок '_':
(1 to 100) reduce (_ + _)
|
Scheme, Common Lisp
|
|
SML
|
|
Swift
|
// 1 вариант
let f: (Int, Int) -> Int = { x, y in return x + y }
// 2 вариант
let f: (Int, Int) -> Int = { x, y in x + y }
/* С сокращенными именами параметров */
// 1 вариант
let f: (Int, Int) -> Int = { return $0 + $1 }
// 2 вариант
let f: (Int, Int) -> Int = { $0 + $1 }
|
TypeScript
|
// Стрелочная функция (arrow function expression) всегда объявляется без имени
(x, y) => x + y
// Выражение функции (function expression) без имени
function(x, y) { return x + y }
// Динамическое создание функции
// конструктором объекта Function (Function constructor)
// всегда объявляется без имени
new Function('x', 'y', 'return x + y')
// Более короткая запись динамического создания функции.
// Вызов функции Function автоматически вызывает
// конструктор Function с теми же параметрами
Function('x', 'y', 'return x + y')
|
Visual Prolog
|
|
См. также
Примечания
- ↑ анонимные функции (неопр.). Дата обращения: 21 февраля 2016. Архивировано 21 февраля 2016 года.
- ↑ C++11. Лямбда-выражения (неопр.). Дата обращения: 25 августа 2010. Архивировано 9 октября 2010 года.
- ↑ Sutter, Herb. Trip Report: ISO C++ Spring 2013 Meeting (неопр.). isocpp.org (20 апреля 2013). Дата обращения: 14 июня 2013. Архивировано 20 августа 2017 года.
- ↑ Стрелочные функции (рус.) (HTML). MDN web docs. Mozilla Developer Network. Дата обращения: 27 сентября 2019. Архивировано 19 августа 2019 года.
- ↑ ECMAScript Language Specification. Edition 3 Final (англ.) (PDF). Архив mozilla.org P. 79. Switzerland, CH-1204 Geneva, 114 Rue du Rhône: ECMA (24 марта 2000). — Спецификация стандарта ECMAScript (ECMA-262). Третья редакция. Дата обращения: 27 сентября 2019. Архивировано 24 сентября 2019 года.
- ↑ Функции в JavaScript (рус.) (HTML). MDN web docs. Mozilla Developer Network. Дата обращения: 27 сентября 2019. Архивировано 3 сентября 2019 года.
- ↑ ECMAScript. A general purpose,
cross-platform programming
language (англ.) (PDF). Архив mozilla.org P. 63-64. Switzerland, CH-1204 Geneva, 114 Rue du Rhône: ECMA (июнь 1997). — Спецификация стандарта ECMAScript (ECMA-262). Первая редакция. Дата обращения: 27 сентября 2019. Архивировано 27 сентября 2019 года.
- ↑ Function (рус.) (HTML). MDN web docs. Mozilla Developer Network. — Описание объекта-функции Function и конструктора Function для динамического создания функций. Дата обращения: 27 сентября 2019. Архивировано 23 сентября 2019 года.
- ↑ Mathematica Documentation: Function (&) Архивировано 5 апреля 2008 года.
- ↑ Function (&) (неопр.). Wolfram Language & System - Documentation Center. Wolfram. Дата обращения: 28 сентября 2019. Архивировано 1 октября 2019 года.
- ↑ perldoc perlref Архивная копия от 2 января 2018 на Wayback Machine (англ.)
- ↑ PHP-Дайджест № 152 (11 – 25 марта 2019) (неопр.). Дата обращения: 7 мая 2019. Архивировано 7 мая 2019 года.
- ↑ M. Zandstra, “PHP Objects, Patterns, and Practice”, second edition, Ed. Apress, 2008.
- ↑ PHP Manual (неопр.). Дата обращения: 1 мая 2010. Архивировано 16 февраля 2013 года.
- ↑ PHP Manual (неопр.). Дата обращения: 1 мая 2010. Архивировано 10 августа 2011 года.
- ↑ Simplifying Data Manipulation in PowerShell with Lambda Functions (неопр.). Дата обращения: 27 сентября 2019. Архивировано 27 сентября 2019 года.
- ↑ Раздел учебника «Освой Python за 24 часа самостоятельно» Архивировано 30 апреля 2006 года.
- ↑ Описание в книге «Programming Ruby» Архивировано 11 апреля 2006 года. (англ.)
|