so_brave 发表于 2011-05-18 12:40

关于闭包及 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]
查看完整版本: 关于闭包及 lambda 函数