关于闭包及 lambda 函数
关于闭包及 lambda 函数[前言]看到某些人对PHP闭包有较大的误解,催生了我写这篇文章的念头。
首先,引用一下“官方”的解释:所谓“闭包”,指的是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。
用一段JavaScript代码解释一下:function a(x) {
var y = 456;
return function(z) {
alert(x + y + z);
}
}
var b = a(123);
b(789);这里的变量(函数)b 拥有函数 a() 的内部变量(x和y)的环境,或者说绑定了函数 a() 的内部变量作用域,而且这些变量也成为 b 的一部分,这样,就形成了一个简单且典型的“闭包”。(注:接触过JavaScript的人基本都了解这个,我就不多废话了,还不理解什么是“闭包”的,请遵循“内事不决问老婆,外事不决问Google”的原则)
PHP从5.3开始支持闭包,因为引入了 lambda 函数(也就是所谓的匿名函数)和 __invoke 方法。也就是说,PHP中实现“闭包”可以有两种方法。
[方法一]使用 lambda 函数实现“闭包”函数function a($x) {
$y = 456;
return function($z) use ($x, $y) {
echo $x + $y + $z;
};
}
$b = a(123);
$b(789);由于PHP的变量作用域与JavaScript不同,所以绑定变量需要在 lambda 函数定义的 use 子句中指定的。use 子句的用法与给函数传递参数的形式类似,因此,变量默认是值传递,我们可以在变量前加 & 使用引用传递。例如: $n = 1;
$inc = function() use (&$n) { ++$n; };
echo $n . ',';
$inc();
echo $n . ',';
$inc();
echo $n;输出:1,2,3
[方法二]使用 __invoke() 魔术方法,使类本身成为“闭包” class A {
private $x;
private $y = 456;
public function __construct($x) {
$this->x = $x;
}
public function __invoke($z) {
echo $this->x + $this->y + $z;
}
}
$a = new A(123);
$a(789);[后语]闭包函数和 lambda 函数都不是新出现的概念,但它们能使我们的编程更加灵活和有趣。也许还有更多实现闭包的方式我还没想到的,欢迎拍砖!
页:
[1]