Разница между лямбда-функцией и закрытием (в 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
- Анонимная функция, которая может быть назначена переменным или передана другим функциям в качестве аргумента.
- Он не может называться как регулярная функция, поскольку он не имеет имени. Это должно либо назначить его переменной, либо передать ее другой функции в качестве аргумента. Таким образом, он становится лямбда-функцией.
- Это полезно, потому что это функция выброса, которую вы можете использовать один раз в определенном месте, только без необходимости повторного использования ее во многих местах.
Закрытие