Разница между лямбда-функцией и закрытием (в PHP)?

В главе 2 "Руководства разработчика Magento PHP" указано:

Zend Framework 2 использует 100% объектно-ориентированный код и использует большую часть новые возможности PHP 5.3, а именно пространства имен, поздняя статическая привязка, лямбда-функции и замыкания.

В то время как post В чем разница между "закрытием" и "лямбдой" ? имеет некоторые ответы (например, что лямбда - это просто анонимная функция, а закрытие - это функция, которая может обращаться к переменным не в списке параметров), кажется, специфична для языка программирования Python (с некоторым упоминанием языка программирования Схемы). Например, согласно сообщению, в Python, кажется, могут быть замыкания, которые не являются лямбдами, и лямбдами, которые не являются закрывающими.

Однако меня интересует язык программирования PHP, а не Python. Один из приведенных ниже ответов показывает, что в PHP все замыкания - это лямбда, что противоречит тому, что сообщение, относящееся к состояниям Python.

Мне кажется, что эти понятия различаются в деталях от языка к языку, и меня интересует PHP, отсюда этот пост.

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

http://en.wikipedia.org/wiki/Closure_%28computer_science%29

хотя в PHP нет примеров.

Ответы

Ответ 1

Закрытие - это лямбда-функция в php, которая инкапсулирует переменные, поэтому их можно использовать, когда их исходные ссылки выходят за рамки.

Закрытие является лямбда-функцией, но лямбда-функция не является замыканием, если вы не укажете ключевое слово use.

Это гораздо лучший ответ: fooobar.com/questions/4901/...

Ответ 2

Существует статья, специфичная для PHP, с подробными пояснениями и примерами кода: http://www.ibm.com/developerworks/library/os-php-5.3new2/

Предупреждение о неработающей ссылке: по состоянию на 2014-10-18, указанная выше ссылка - 404. Я скопировал статью из кеша Google и разместил здесь:

Если вы обнаружите, что исходный документ снова появился, сообщите мне.

Ответ 3

Функция Lambda назначается переменной или передается другой функции в качестве параметра. Закрытия используют переменные из-за пределов их возможностей.

Использование lambdas

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

// Anonymous function
// assigned to variable
$greeting = function () {
  return "Hello world";
}

// Call function
echo $greeting();
// Returns "Hello world"

Чтобы использовать анонимную функцию, мы назначаем ее переменной, а затем вызываем эту переменную как функцию.

Вы также можете передать функцию другой функции, например:

// Pass Lambda to function
function shout ($message){
  echo $message();
}

// Call function
shout(function(){
  return "Hello world";
});

Что такое закрытие?

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

Например:

// Create a user
$user = "Philip";

// Create a Closure
$greeting = function() use ($user) {
  echo "Hello $user";
};

// Greet the user
$greeting(); // Returns "Hello Philip"

Как вы можете видеть выше, Closure может получить доступ к переменной $user, поскольку она была объявлена ​​в предложении use определения функции Closure.

Если вы изменили переменную $user в Closure, это не повлияет на исходную переменную. Чтобы обновить исходную переменную, мы можем добавить амперсанд. Амперсанд перед переменной означает, что это ссылка, поэтому исходная переменная также обновляется.

For example:
// Set counter
$i = 0;
// Increase counter within the scope
// of the function
$closure = function () use ($i){ $i++; };
// Run the function
$closure();
// The global count hasn't changed
echo $i; // Returns 0

// Reset count
$i = 0;
// Increase counter within the scope
// of the function but pass it as a reference
$closure = function () use (&$i){ $i++; };
// Run the function
$closure();
// The global count has increased
echo $i; // Returns 1

Этот текст является частью статьи Филиппа Брауна на → culttt.com. Здесь вы можете найти еще несколько примеров.

Ответ 4

Закрытие на самом деле означает, что если вы use переменная, его значение будет использоваться внутри закрытой функции, не обновляя ее значение вне ее. Вместо этого вам нужно использовать ссылочный оператор &, если вы хотите обновить значение используемой переменной, но как обычный аргумент.

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

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

Ответ 5

Функция

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

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

  • Функция, не имеющая имени.
  • Не обязательно создавать закрытие.

Lambda

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

Закрытие

  • То же самое, что и лямбда. Но он может обращаться к переменным извне, не используя глобальные переменные. (он может захватить состояние окружающей среды).
  • С помощью синтаксиса "use" можно работать с ограничениями видимости переменной по-разному. (В основном это анонимная функция с синтаксисом использования).
  • Он не создан только для анонимных функций.
  • Это умнее, чем Лямбда в том смысле, что он имеет возможность взаимодействовать с переменными из внешней среды.