关于 php.net 关于匿名函数教程的问题


Questions about php.net's tutorial on Anonymous Functions

PHP.net关于匿名函数的文档的示例3让我陷入了循环。

第一个 echo 语句打印了$message的值,即使文档让我相信这行不通。

闭包也可以从父作用域继承变量。任何此类变量都必须传递给 use 语言构造。:

// No "use"
$example = function () {
    var_dump($message);
};
echo $example();

输出不是失败,而是:

Notice: Undefined variable: message in /example.php on line 6
NULL
string(5) "hello"

在第三个回显语句之前,出现:

$message = 'world';

然后,echo 调用该函数,再次$example以获取 $message 的值。再次string(5) "hello"输出,而不是string(5) "world"。由于值$message是在定义$example时定义的,因此 echo 语句仍返回 string(5) "hello" 。我明白了。

接下来,$message"重置"为"hello"。再次调用 Echo,但这次函数$example引用了$message:

$example = function () use (&$message) {
    var_dump($message);
};

输出为 string(5) "world" 。我完全不明白这一点。我以为消息的值已重置为你好?

为什么第一个回声仍然有效?为什么第四个打印"世界"?

示例输出

Notice: Undefined variable: message in /example.php on line 6
1: NULL
2: string(5) "hello"
3: string(5) "hello"
4: string(5) "hello"
5: string(5) "world"
6: string(11) "hello world"

第一个回显示例

从示例代码来看,第一个 echo 语句似乎只是导致NULL,因为此匿名函数不包含use(Notice让您知道$message未定义。

以下是上下文中的相关代码以供参考:

$message = 'hello';
// No "use"
$example = function () {
    var_dump($message);
};
echo $example();

第五个回声示例

虽然 $message 的值已重置为 hello ,但以下代码部分:

// Inherit by-reference
$example = function () use (&$message) {
    var_dump($message);
};
echo $example();

表明$message是通过引用继承的,这意味着当以后使用$message = 'world';时,我们现在引用(并分配"world"(与之前相同的$message变量。

换句话说,当我们定义$example函数时,我们指向内存中的原始$message变量(通过&$message引用(。因此,当我们稍后在代码中调用$example()时,我们指的是相同的原始$message变量(我们最近也用$message = 'world';行进行了更改(。这意味着$example()将输出我们当前的$message(当前设置为 "world" (,而不是先前设置的值。

以下是上下文中的相关代码以供参考:

// Reset message
$message = 'hello';
// Inherit by-reference
$example = function () use (&$message) {
    var_dump($message);
};
echo $example();
// The changed value in the parent scope
// is reflected inside the function call
$message = 'world';
echo $example();
我认为

您可能混淆了导致混淆的var_dump值。让我们分解一下:

最初设置消息

$message = 'hello';

定义函数。使用$message作为当前值在定义函数时。所以在这里,除非重新定义$example,否则输出将始终string(5) "hello",因为这是定义函数时$message设置的。

$example = function () use ($message) {
    var_dump($message);
};
echo $example(); // Result = string(5) "hello"

即使我们切换$message的值原始函数在以下情况下使用 $message 的值定义了该函数,因此输出 string(5) "hello"

$message = 'world';
echo $example(); // Result = string(5) "hello"

在继续下一个示例之前将消息重置为"hello">

$message = 'hello';

当使用&$message定义时,这是说"使用$message当前值",而不是在定义函数时保留$message的值。因此,由于$message当前设置为 "hello" ,该函数表示这一点。如果我们$message更改为其他内容并再次运行该函数,它将转储设置$message值的任何内容。

$example = function () use (&$message) {
    var_dump($message);
};
echo $example(); // Result = string(5) "hello"

这表明当函数中的&$message值在外部更改时,该值会更新。

$message = 'world';
echo $example(); // Result = string(5) "world"