PHP中匿名函数中的闭包和引用&

6

我有:

function outside( $limit ) {

$tally = 0;

    return function() use ( $limit, &$tally ) {
        $tally++;

        if( $tally > $limit ) {
            echo "limit has been exceeded";
        }
    };
}

$inside = outside( 2 );
$inside();
$inside();
$inside();

输出结果:超过限制

我的理解:

  1. $inside = outside(2);中,返回匿名函数并将其分配给变量$inside。匿名函数使用$limit(2)和$tally(0)的值。

  2. 调用函数$inside()。这将$tally递增到1。该值被记住,$limit也是如此。为什么在$tally前面要加上&符号?我知道它用于创建引用,但在这种情况下,它让我感到困惑。这个闭包如何记住$limit的值?

任何官方文档的参考资料都会有所帮助!


现在有一些有趣的代码!好久没见过那种东西了。 - matrixdevuk
2
我实际上抗议这个问题是一个重复的问题。虽然它非常相似,但这个问题更关注传递的变量是按引用传递而不是use关键字本身的使用。 - Scopey
2个回答

7

匿名函数在php中实际上是Closure对象。如果您将var_dump($invoke)添加到您的代码中,您会看到这个:

object(Closure)#1 (1) {
  ["static"]=>
  array(2) {
    ["limit"]=>
    int(2)
    ["tally"]=>
    int(0)
  }
}

use关键字所引用的变量存储在闭包对象的static数组中。当调用闭包时,这些变量会像普通参数一样传递给函数。因此,如果不使用引用,它们将被复制并传递,而且在函数中对它们的任何更改都没有效果。


当$limit没有被声明为引用时,它的值如何在后续调用中保持不变? - Robert
哦,好的,因为它是闭包对象的静态属性,所以该值在后续调用中保持不变?我现在理解得更好了。 - Robert

4
< p > & 表示传递参数的方式为引用而非值。这意味着您可以在函数内部更改变量,并且它将在外部记忆 - 不仅仅在该函数中。

通过将该函数分配给$inside,您有效地保留了对变量的引用,因此它将从一次调用到下一次调用被记住。

参见PHP: Passing by Reference


我认为在函数内部,“static”关键字用于“记住”目的,而不是使用&符号来记住。 - Robert
是的,那样做可以行得通,但 & 意味着你可以从函数外部传递变量,比如对象的引用或全局值(每次不是同一个变量),也就是说它必须被设置为函数外部的一个变量。 - worldofjr
你也可以通过值(不使用&)传递变量,然后从函数中返回该值并将其设置为相同的变量。这在功能上是相同的。但是,如果您需要一个函数来更改两个变量(例如),那么这就变得更加复杂了。 - worldofjr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接