在匿名函数中使用变量,该函数在其他地方定义
Posted
技术标签:
【中文标题】在匿名函数中使用变量,该函数在其他地方定义【英文标题】:Use variables inside an anonymous function, which is defined somewhere else 【发布时间】:2012-12-17 19:33:59 【问题描述】:在 php 中使用匿名函数时,您可以通过使用 use()
关键字轻松地使用其范围之外的变量。
在我的例子中,匿名函数已经在某处定义,但稍后(在其他地方)在一个类中调用。
下面这段代码是为了说明这个想法:
<?php
$bla = function ( $var1 ) use ($arg)
echo $var1;
;
class MyClass
private $func;
public function __construct ( $func )
$this->func = $func;
public function test ( $arg )
$closure = $this->func;
$closure ( 'anon func' );
$c = new MyClass($bla);
$c->test ( 'anon func' );
我正在做的是创建一个anonymous function
并将其存储在一个变量中。我将该变量传递给一个类的方法,这就是我想要运行 anonymous 函数的地方。
但是我不能使用use()
关键字从method
获取$arg
参数这种方式。因为 anonymous 函数是在 method
之外声明的。
但我确实需要一种方法来从运行匿名函数的方法中获取变量。当匿名函数在其他地方声明时,有没有办法做到这一点..?
【问题讨论】:
将其作为参数传递。 @NiclasLarsson 我不能那样做。因为我需要一种通过reference
在anonymous function
中更改参数的方法。我可以通过func_get_args
从test()
方法内部轻松获取值。然后在那里将这些值传递给anonymous function
,但这样它只会获得copy
的值。我需要给它一个reference
。
您不能使用引用运算符 (&) 通过引用传递它们吗?
@NiclasLarsson 通过引用不会使其改变范围。在 OP 的示例中, $arg 仍将指向全局范围内的 $arg 。我知道 OP 希望闭包使用 $arg 从它执行的范围内,例如MyClass::test($arg)。但也许 OP 可以澄清一下。
【参考方案1】:
FWIW,如果你使用 use reference
(php.net ex 3.3) 和一个全局的,丑陋的,因为它使用全局变量,你可以做到这一点,但只是把它放在那里:
<?php
$bla = function ( $var1 ) use (&$arg)
return "var1:$var1, arg:$arg";
;
class MyClass
private $func;
public function __construct ( $func )
$this->func = $func;
public function test ( $param )
global $arg;
$arg=$param;
$closure = $this->func;
return $closure ( 'anon func' );
$c = new MyClass($bla);
echo $c->test ( 'bla bla' ); //var1:anon func, arg:bla bla
【讨论】:
【参考方案2】:use
关键字的意义在于将inherit/close over a particular environment state from the parent scope 插入到闭包中当它被定义时,例如
$foo = 1;
$fn = function() use ($foo)
return $foo;
;
$foo = 2;
echo $fn(); // gives 1
如果您希望 $foo
稍后关闭,请稍后定义关闭,或者如果您希望 $foo
始终为当前值 (2),请将 $foo
作为常规参数传递。
【讨论】:
希望我忽略了一些东西。但显然没有其他方法可以将所需的变量作为参数传递。 你应该提到它叫做“词法作用域”。所有现代编程语言都使用词法作用域。以上是关于在匿名函数中使用变量,该函数在其他地方定义的主要内容,如果未能解决你的问题,请参考以下文章
Kotlin函数 ⑤ ( 匿名函数变量类型推断 | 匿名函数参数类型自动推断 | 匿名函数又称为 Lambda 表达式 )