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

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

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

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

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

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

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

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

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

5 ответов

Решение

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

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

Это гораздо лучший ответ: /questions/35183779/v-chem-raznitsa-mezhdu-zamyikaniem-i-lyambdoj/35183795#35183795

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

Используя лямбды

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

// 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";
});

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

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

Например:

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

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

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

Как вы можете видеть выше, Закрытие может получить доступ к $user переменная, потому что она была объявлена ​​в предложении использования определения функции 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. Вы можете найти еще несколько примеров там.

Есть статья для PHP с подробным объяснением и примерами кода: http://www.ibm.com/developerworks/library/os-php-5.3new2/

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

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

функция

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

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

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

лямбда

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

закрытие

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

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

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

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

Другие вопросы по тегам