在单个语句中创建和调用匿名函数

Posted

技术标签:

【中文标题】在单个语句中创建和调用匿名函数【英文标题】:Creating and invoking an anonymous function in a single statement 【发布时间】:2011-04-06 01:22:22 【问题描述】:

一个 php 闭包或匿名函数用于创建函数而不指定它的名称。

是否可以像在 javascript 中那样在不分配标识符的情况下调用它们? 例如

(function()
    echo('anonymous function');
)();

在定义匿名函数时,use 构造的正确用法是什么?匿名函数在可访问私有属性的公共方法中的状态如何?

$anon_func = 
function($my_param) use($this->object_property) //use of $this is erroneous here
    echo('anonymous function');
;

【问题讨论】:

闭包并不完全等同于匿名函数,尽管 PHP 中的匿名函数属于 Closure 类型。让你知道。 当您尝试第二个代码示例时,确切的错误是什么? “错误”有点不具体。 不能使用 $this 作为词法变量 OP:由于 PHP 5.4 的变化,我已经更新了我的答案;不要问我他们为什么这样做。 cc @BoltClock 【参考方案1】:

PHP 7 添加了执行此操作的功能。

这段代码:

(function()  echo "This works as expected in PHP 7.\n"; )();

在 PHP 7 中可以正常工作。(在任何 PHP 5.x. 版本中仍然无法正常工作)

【讨论】:

【参考方案2】:
call_user_func(function() use(closure-vars) ... );

【讨论】:

OP 如何使闭包可以访问类属性? op可以通过use语句创建对象的引用传递给闭包,即:$obj = $this; call_user_func(function() 使用 ($obj))。这样他就可以访问闭包内的类属性和方法。有点 hack,但它是 PHP 5.4 到来之前我们拥有的最好的。【参考方案3】:

是否可以在没有的情况下调用它们 像我们一样分配给标识符 JavaScript 吗?例如

PHP 5.x 中没有;除非当您的方法将回调作为参数时计算它。例如:

$square = array_map(function ($v)  return $v*$v; , $array);

use的正确用法是什么 在定义匿名的同时构造 功能

use 关键字指示应将当前词法范围中的哪些变量导入闭包。您甚至可以通过引用传递它们并更改正在传递的变量,例如:

$total = 0;
array_walk($array, function ($v) use (&$total)  $total += $v; );
// $total is now the sum of elements in $array

匿名状态是什么 在公共方法中使用 访问私有属性?

在类中定义的闭包可以完全访问其所有属性和方法,包括私有的,无需通过 PHP 5.4 中的关键字 use 导入 $this

// this works fine in PHP 5.4
$anon_func = 
function($my_param)  
    $thing = $my_param + $this->object_property;
    echo('anonymous function');
;

请注意,由于某些奇怪的原因,在闭包 was removed in PHP 5.3 中支持 $this。在此版本中,您可以使用以下方法解决此限制:

// a workaround for PHP 5.3
$temp = $this;

$anon_func = 
function($my_param) use ($temp)  
    $thing = $my_param + $temp->object_property;
    echo('anonymous function');
;

但这只能让您访问公共成员,尝试访问私有成员仍然会给您一个错误。

另请注意,无论 PHP 版本如何,尝试导入 $this(通过 use)都会导致致命错误 Cannot use $this as lexical variable

【讨论】:

+1 但是,在 PHP 中无法自行调用像 (function() )(); 这样的匿名函数,原因可能与 Marc B 指出的同样的原因,数组取消引用也不可行。 @BoltClock BTW 数组解引用(例如:function foo() return $someArray; $var = foo()['bar'])也适用于 PHP 5.4【参考方案4】:

看起来不像,因为它们仍然必须使用 function() 表示法声明,并且在我的 5.3.2 安装中,尝试您的示例概念会返回 unexpected '(' 语法错误。闭包上的doc page 也没有提及。

也许一旦他们修补解析器以允许 somefunction()[2] 数组取消引用,这将成为可能。

【讨论】:

数组解引用已添加到PHP 5.4,但您仍然不能在声明后立即调用匿名函数。【参考方案5】:

示例 1

(new class 
    function __invoke($n) 
        echo "in PHP 7.\n";
    
)(0);

示例 2

(function()  echo "in PHP 7.\n"; )();

示例 3

call_user_func(function()  echo "in php> 5.6\n"; );

【讨论】:

以上是关于在单个语句中创建和调用匿名函数的主要内容,如果未能解决你的问题,请参考以下文章

js匿名函数

JavaScript之 ------ 函数(一般函数动态函数匿名函数)

golang之匿名函数结合defer

(二十)python 3 匿名函数

匿名函数lambda

函数——基本语法,嵌套匿名高阶递归函数