lambda 函数和闭包(在 PHP 中)之间的区别?
Posted
技术标签:
【中文标题】lambda 函数和闭包(在 PHP 中)之间的区别?【英文标题】:Difference between a lambda function and a closure (in PHP)? 【发布时间】:2013-11-24 17:16:15 【问题描述】:“Magento php 开发人员指南”第 2 章指出:
Zend Framework 2 使用 100% 面向对象的代码并利用大部分 PHP 5.3 的新特性,即命名空间、后期静态绑定、 lambda 函数和闭包。
虽然What is the difference between a 'closure' and a 'lambda'? 的帖子有一些答案(例如,lambda 只是一个匿名函数,而闭包是一个可以访问不在其参数列表中的变量的函数),但似乎特定于 Python编程语言(其中提到了 Scheme 编程语言)。 例如,根据帖子,在 Python 中,似乎可以有不是 lambda 的闭包,也可以有不是闭包的 lambda。
但是,我对 PHP 编程语言感兴趣,而不是 Python。下面的答案之一似乎指出,在 PHP 中,所有闭包都是 lambda,这与与 Python 状态相关的帖子相冲突。
在我看来,这些概念的细节因语言而异,我对 PHP 很感兴趣,因此发了这篇文章。
所有这些都令人困惑。虽然我认为 lambda 函数通常只是未命名的函数,但以下 Wikipedia 文章更多地介绍了闭包:
http://en.wikipedia.org/wiki/Closure_%28computer_science%29
虽然在 PHP 中没有示例。
【问题讨论】:
你可以先搜索再问;这是同样的问题:***.com/questions/220658/… 以下来自 Philip Brown 的 article 很好地总结了 closure 和 lambda 函数之间的区别。还提供了很好的例子。 【参考方案1】:闭包是 php 中的一个 lambda 函数,它封装了变量,因此一旦它们的原始引用超出范围,就可以使用它们。
闭包是 lambda 函数,但 lambda 函数不是闭包,除非您指定 use
关键字。
这是一个更好的答案:https://***.com/a/220728/1152375
【讨论】:
谢谢。我发现有一个通用的答案。在那个线程中写的是 lambda 函数只是一个匿名函数,而闭包是访问可以在函数外部找到的变量的任何函数(这与您上面的答案不匹配,即每个闭包都是一个 lambda 函数,因为根据前面提到的线程,闭包可以有一个名称,只要它访问全局范围)。 这对 PHP 是否正确?我想每种语言都以稍微不同的方式定义这些概念,而我的问题是针对 PHP 的。 PHP中这些的确切定义是什么?谢谢。 @JohnSonderson:“闭包”和“匿名函数”的概念与语言无关 @newacct 概念和实现可以是两个不同的东西。例如PHP函数不能自动访问全局作用域的环境,PHP手册在php.net/manual/en/class.closure.php的第一行专门定义闭包对象类型为“匿名函数” PHP 实现闭包的另一个重要区别是,默认情况下提供给函数的环境不是由引用变量构成的。 wiki.php.net/rfc/closures#references_vs_copies【参考方案2】:有一篇PHP专用的文章有详细的解释和代码示例: http://www.ibm.com/developerworks/library/os-php-5.3new2/
断开链接警告:截至 2014 年 10 月 18 日,上述链接为 404。 我从谷歌缓存中复制了这篇文章并放在here:
如果您发现原始文档在任何地方重新出现,请告诉我。
【讨论】:
文章原链接又出现了。【参考方案3】:闭包实际上意味着如果你use
一个变量,它的值将在一个封闭的函数内使用,而不是在它之外更新它的值。如果您想更新已使用变量的值但作为普通参数,则必须使用引用运算符 &
。
这就是它的强大用途,您可以在没有依赖全局命名空间的常规函数的情况下更轻松地增加/递减类似的东西或创建斐波那契或迭代生成器函数。
Lambda 不支持use
,因此它们不能包含外部范围的变量。闭包也可以被缓存,因此它提高了编译性能。
【讨论】:
【参考方案4】: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"
正如您在上面看到的,闭包能够访问$user
变量,因为它是在闭包函数定义的 use 子句中声明的。
如果您要更改闭包中的$user
变量,它不会影响原始变量。要更新原始变量,我们可以附加一个 & 符号。变量前的 & 表示这是一个引用,因此也会更新原始变量。
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
本文是 Philip Brown 文章的一部分,位于 >> culttt.com。您可以在此处找到更多示例。
【讨论】:
【参考方案5】:功能
一段代码以参数的形式接受一个或多个输入,进行一些处理并返回一个值。 它应该有一个名字,需要时可以用它的名字来调用。 可以将多个函数包装在一个类中(以允许拥有多个同名的函数等等)。匿名函数
一个没有名字的函数。 不一定需要创建闭包。Lambda
可以分配给变量或作为参数传递给其他函数的匿名函数。 它不能像普通函数一样被调用,因为它没有名称,它必须要么将它分配给一个变量,要么将它作为参数传递给另一个函数。因此它变成了一个 Lambda 函数。 它很有用,因为它们是一种一次性功能,您可以只在某个地方使用一次,而无需在许多地方重复使用它。关闭
与 Lambda 相同。但它可以在不使用全局变量的情况下从外部范围访问变量。 (它可以捕捉周围环境的状态)。 可以使用“use”语法以简洁的方式解决变量范围限制。 (基本上它是一个使用 use 语法的匿名函数)。 它不仅是为匿名函数创建的。它比 Lambda 更智能,因为它能够与来自外部环境的变量进行交互。
【讨论】:
以上是关于lambda 函数和闭包(在 PHP 中)之间的区别?的主要内容,如果未能解决你的问题,请参考以下文章