Kotlin. Анонимные функции

Статья проплачена кошками — всемирно известными производителями котят.

Если статья вам понравилась, то можете поддержать проект.

В Kotlin часто используется особый вид функций — анонимные функции. Функции можно не давать имя после ключевого слова fun и она станет анонимной.

val a: (Int) -> Int = fun(i: Int) = i + 3
println(a(4)) // 7

Анонимная функция прибавляет к заданному значению число 3.

В некоторых случаях анонимные функции удобны и полезны. Например, мы можем добавить новые правила к существующим функциям.

В стандартной библиотеке есть функция count() для подсчёта числа символов в строке.

val charNumber = "Васька".count()
println(charNumber) // выводит 6

Есть перегруженная версия функции, в которой можно вызвать анонимную функцию в качестве аргумента. Зададим новое правило — подсчитать количество символов а в этом же слове.

val charNumber = "Васька".
count({letter -> letter == 'а'}) println(charNumber) // выводит 2

Функция count() использует анонимную функцию, чтобы решить, как считать символы в строке. Она последовательно передаёт анонимной функции символ за символом, и если та вернёт истинное значение для заданного символа, общий счёт нужных символов увеличивается на единицу. Как только будет проверен последний символ, функция count() возвратит итоговое значение. Это одно из применений анонимных функций.

Если заглянуть под капот, то увидим, что функция принимает анонимную функцию в аргументе типа (Char) -> Boolean с именем predicate. Функция predicate принимает аргумент Char и возвращает булево значение.

public inline fun CharSequence.count(
    predicate: (Char) → Boolean
): Int

Создадим собственную анонимную функцию для вывода какого-то сообщения.

println(
        {
            val year = 2019
            "Добро пожаловать в $year год"
        }()
)

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

Анонимные функции имеют специальный функциональный тип. Переменные этого типа могут содержать анонимные функции и использоваться как обычные переменные.

Объявим переменную, которая будет содержать обычную функцию, которая в свою очередь будет иметь анонимную функцию.

val messageFunction: () -> String =
        {
            val year = 2019
            "Добро пожаловать в $year год"
        }
println(messageFunction())

Разберём синтаксис. Сначала объявляется переменная messageFunction. После имени переменной идёт двоеточие и функциональный тип. Функциональный тип объявляется в виде конструкции () -> String (вместо String могут быть другие типы, в зависимости от задачи) и сообщает компилятору, какой тип функции содержится в переменной.

В нашем случае мы можем использовать любую функцию без аргументов (пустые скобки), которая возвращает строку.

У анонимных функции не используется ключевое слово return, однако функция неявно и автоматически возвращает результат последней инструкции в теле функции.

Пример можно написать без определения типа, полагаясь на автоматическое определение типов.

val messageFunction =
        {
            val year = 2019
            "Добро пожаловать в $year год"
        }
println(messageFunction())

Разберём случаи с аргументами. Перепишем предыдущий пример, добавив один аргумент.

val messageFunction: (String) -> String =
        {
            catName ->
            val year = 2019
            "$catName! Добро пожаловать в $year год"
        }
println(messageFunction("Васька"))

Мы указали, что анонимная функция принимает строку. Имя строкового параметра определяется внутри функции, сразу после открывающей фигурной скобки, и за ним следует стрелка.

Здесь также можно использовать автоматическое определение типов и сократить код. Но в этом случае у параметров следует указать тип.

val messageFunction =
        {
            catName: String ->
            val year = 2019
            "$catName! Добро пожаловать в $year год"
        }
println(messageFunction("Васька"))

Если функция сложная, то лучше избегать автоматического определения типов, чтобы код было читаемым.

Ключевое слово it

В анонимной функции, в которой применяется только один аргумент, вместо имени параметра можно использовать альтернативный вариант — ключевое слово it.

Переделаем предыдущий пример. Удаляем имя параметра и стрелку в начале анонимной функции и добавляем it.

val messageFunction: (String) -> String =
        {
            val year = 2019
            "$it! Добро пожаловать в $year год"
        }
println(messageFunction("Васька"))

Ключевое слово it удобно тем, что не требует имени переменной. Но с другой стороны при сложном коде страдает читаемость кода. Нужно соблюдать баланс и использовать подобную возможность в коротких выражениях, где понимание кода не вызовет трудностей:

// другой вариант примера из начала статьи
val charNumber = "Васька". count({it -> it == 'а'})
println(charNumber) // выводит 2
// оптимизированный вариант без круглых скобок
val charNumber = "Васька".count { it -> it == 'а'}
println(charNumber) // выводит 2

Несколько аргументов

Напомню, что it можно использовать только для одного аргумента. Если анонимная функция использует несколько аргументов, то используйте именованные переменные.

val messageFunction: (String, Int) -> String =
        { catName, age ->
            val year = 2019
            "$catName! Добро пожаловать в $year год. Вам исполнилось $age лет"
        }
println(messageFunction("Васька", 5))

Выражение теперь объявляет два параметра, catName и age, и принимает два аргумента. Так как теперь больше одного параметра в выражении, ключевое слово it использовать нельзя.

Подобного рода анонимные функции называют лямбдами, и им посвящена ещё одна статья.

Дополнительное чтение

Реклама

Анонимная функция | это.

.. Что такое Анонимная функция?

ТолкованиеПеревод

Анонимная функция

Анонимная (безымянная) функция — в программировании особый вид функций, которые объявляются в месте использования и не получают уникального идентификатора для доступа к ним. Обычно при создании они либо вызываются напрямую, либо ссылка на функцию присваивается переменной, с помощью которой затем можно косвенно вызывать данную функцию.

Синтаксис

Синтаксис записи анонимных функций для различных языков программирования в большинстве случаев сильно различается.

ЯзыкПример записи сложения
AS3
function(x:int, y:int):int{return x + y;}
C#
(x,y) => x+y
C++11Общая форма:
[capture](parameters)->return-type{body}

или

[capture](parameters){body}

Пример:

[](int x, int y){ return x + y; }
[1]
CoffeeScript
(x, y) -> x + y
D
delegate(int x, int y){ return x+y; }
Delphi (c 2009 версии)
function(x, y: integer): integer 
begin
  result := x+y;
end;
Erlang
fun(X,Y)->X+Y end
GNU Octave
@(x,y)x+y
Groovy
{x,y->x+y}
Haskell
\x y -> x + y
JavaScript
function(x,y) {return x+y}
[2]
Lua
function(x,y) return x+y end
Maple
(x, y) -> x + y
Mathematica
#1+#2&

или

Function[#1+#2]

или

Function[{x,y},x+y]
[3]
MATLAB
f=@(x,y) x+y
Perl
sub { return $_[0] + $_[1] }
[4]
PHP
// PHP 5. 3
function($x, $y) { return $x + $y; }

[5]

// PHP 4 >= 4.0.1, PHP 5
create_function('$x, $y', 'return $x + $y;')

[6]

Python
lambda х, у: х+у
[7]
R
function(x,y) x+y
Ruby
proc{|x,y| x + y }
[8]
Scheme
(lambda (x y) (+ x y))

Примечания

  1. C++11. Лямбда-выражения
  2. Описание в справочнике «Ядро JavaScript»
  3. Mathematica Documentation: Function (&)
  4. perldoc perlref (англ.)
  5. PHP Manual
  6. PHP Manual
  7. Раздел учебника «Освой Python за 24 часа самостоятельно»
  8. Описание в книге «Programming Ruby» (англ.)

См. также

  • Замыкание (программирование)
  • Лямбда-исчисление
  • Callback (программирование)

Wikimedia Foundation. 2010.

Игры ⚽ Нужна курсовая?

  • Стивен Франклин
  • Лотяну, Эмиль Владимирович

Полезное


PHP — P39: Анонимные функции. Анонимная функция — это функция… | Автор: Dino Cajic

Опубликовано в

·

Чтение: 4 мин.

·

19 августа 2020 г.

Анонимные функции, или замыкания, — это функции, которые вызывают у людей сильный стресс. с жизнью. Упростим этот процесс. Анонимная функция — это функция без имени.

Давайте посмотрим на обычную функцию. Обычная функция начинается с функции 9.ключевое слово 0018, за которым следует имя функции; параметры заключены в круглые скобки, а тело функции заключено в фигурные скобки.

Анонимная функция удаляет имя функции и присваивает функцию переменной.

Давайте создадим реальный пример. Мы покажем как стандартную функцию, так и объявление анонимной функции. Начнем с обычной функции. Функция называется stuff_dogs_say() . будет всего эхо из «Собака говорит, что кошки сосут» после того, как ее вызвали. Мы уже рассмотрели, как вызывать обычные функции в статье пользовательских функций .

Теперь давайте превратим обычную функцию в анонимную.

Мы создаем переменную с именем $stuff_dogs_say и назначаем ей анонимную функцию. Поскольку мы что-то присваиваем переменной, нам нужно, как всегда, заканчивать оператор присваивания точкой с запятой. Функция разделена на несколько строк для ясности. С $stuff_dogs_say содержит анонимную функцию, мы можем вызвать эту функцию, добавив пару круглых скобок к имени самой переменной: $stuff_dogs_say() .

Мы можем объявлять параметры и передавать аргументы анонимной функции так же, как и в случае с обычными функциями.

Мы объявляем анонимную функцию с параметром $saying и присваиваем ее переменной $stuff_dogs_say_two . Анонимная функция всего эхо из переданного ему аргумента. Во время вызова функции в строке 7 аргумент Cats Stink передается функции $stuff_dogs_say_two .

Давайте посмотрим на кое-что интересное. Мы знаем, что можем вернуть любой тип данных изнутри функции. Это означает, что мы также можем возвращать функции; Я знаю, с ума сошел. Мы собираемся создать обычную функцию, которая возвращает анонимную функцию. Давайте перейдем к примеру и пройдемся по нему.

  1. Мы начинаем с создания обычной функции с именем stuff_cats_say() . Обычная функция просто возвращает анонимную функцию. Анонимная функция содержит оператор echo : здесь нет ничего революционного. Мы знаем, что здесь можно вернуть что угодно, поэтому мы могли бы вернуть целое число (т.е. вернуть 3;) или строку (т.е. вернуть «Дино»; ). На этот раз мы просто возвращаем целую функцию (например, return function() { echo «Dogs Suck»; }; )
  2. Мы назначаем обычную функцию stuff_cats_say() переменной $cats в строке 9. Помните, как работает PHP. Он начинается справа от оператора присваивания. Он оценивает функцию stuff_cats_say() . Эта функция просто возвращает анонимную функцию. Затем эта анонимная функция назначается переменной $cats . Это было бы точно так же, как сказать: $cats = function() { echo «Собаки сосут»; };
  3. Теперь, когда мы знаем, что Переменная $cats содержит анонимную функцию, мы знаем, как вызвать эту анонимную функцию: добавив пару круглых скобок к переменной.
  4. Вызов функции $cats() вызовет анонимную функцию. Что делает анонимная функция? Это всего лишь эхо из Dogs Suck.

Зачем использовать анонимные функции вместо обычных? Иногда вам нужно получить доступ к переменной, которая находится за пределами области действия функции, и по какой-то причине эту переменную нельзя передать в качестве аргумента. Вы можете использовать ключевое слово «use» с анонимной функцией, чтобы получить доступ к области действия этой переменной. Мы рассмотрим ключевое слово «use» в следующей статье.

Использование анонимных функций для фильтров и действий WordPress

Эта статья предоставляется бесплатно. Узнайте, как получить полный доступ к премиум-контенту, включая статьи с инструкциями и форумы поддержки, а также приоритетную поддержку по электронной почте и эксклюзивные расширения плагинов для участников.

Чем больше настроек вы делаете при создании сайта WordPress, тем больше вы обнаружите, что у вас есть много функций, привязанных к действиям и фильтрам. Иногда эти функции могут быть довольно простыми, возвращая всего одну строку текста или заменяя одно слово. Есть ли простой способ сделать это более компактным?

Да, есть! Вот как: 

Вход в анонимную функцию

PHP позволяет использовать функции без имен, известные как анонимные функции. Они также называются замыканиями и часто используются в качестве процедур обратного вызова. Для наших целей это могут быть очень полезные инструменты при настройке настроек для вашей установки WordPress.

Некоторая предыстория

Если вы проделали большую работу по настройке установки WordPress, возможно, вы уже знакомы с тем, как работают фильтры и хуки действий. Но на всякий случай вот простой обзор.

Хуки позволяют нам «привязывать» функции к определенным местам выполнения WordPress (или исполнения темы или плагина). Это могут быть «действия», которые делают что-то, или «фильтры», которые изменяют что-то.

Хотя действия и фильтры служат немного разным целям, их использование практически одинаково. Чтобы «прицепить» что-то к одному из этих элементов, используйте функцию «add_action» или «add_filter» с аргументами для имени хука и функции, которую вы к нему подключаете. (Есть и другие необязательные параметры, но они здесь не обсуждаются.) Это выглядит примерно так:

В этом примере у вас есть соответствующая функция:

Как использовать анонимную функцию

Функция должна иметь уникальное имя, иначе она вызовет ошибку сценария. Когда у вас есть тысячи функций в WordPress и различных плагинах, а также все, что вы добавляете с помощью пользовательских функций в functions.php, избежать конфликтов имен может быть проблемой. Использование анонимной функции позволяет избежать этой проблемы и поместить функцию прямо в вызов add_action или add_filter вместо имени функции. Это делает вещи красивой, плотной упаковкой.

Вот простой пример. Обычным способом мы подключим фильтр excerpt_length к пользовательской функции, чтобы вернуть пользовательское значение длины выдержки:

Вот тот же процесс, но вместо этого используется анонимная функция:

Посмотрите внимательно на приведенное выше — вы заметили, имени функции в вызове add_filter(), мы вставили всю функцию без имени?

Это хорошо упаковывает вещи.

Теперь вам не нужно беспокоиться о том, что другая функция excerpt_length_example() создаст конфликт пространства имен. Это также упрощает задачу, потому что все это упаковано вместе.

Когда НЕ следует использовать анонимные функции

Это отличный инструмент для использования в соответствующей среде. Когда вам НЕ следует использовать анонимную функцию?

Впервые анонимные функции были представлены в PHP 5.3, и их поддержка включена во все последующие версии. Но знаете что? Минимальная версия PHP для WordPress ВСЕ ЕЩЕ требует только PHP 5.2.4. Теперь PHP 5.2 больше не поддерживается проектом PHP, и любой хост, на котором он работает, требует проблем с безопасностью, но имейте в виду, что он может быть там. И ваши анонимные функции для этого не годятся.

Теперь предположим, что вы умны и запускаете текущий PHP. Но вы публикуете пример или что-то еще где-то в Интернете, чтобы кто-то другой мог его прочитать. Не думайте, что (1) они знают, что такое анонимные функции и как и когда их использовать, и (2) что они достаточно умны, чтобы поддерживать PHP в актуальном состоянии, как и вы. Либо не публикуйте анонимную функцию, либо хотя бы дайте какое-то объяснение.

Как насчет создания тем или плагинов? Если вы применяете код, который будет использоваться в широком смысле, например, плагин, то лучше НЕ использовать для этого анонимную функцию.