【问题标题】:Cannot convert a recursive function into an IIFE无法将递归函数转换为 IIFE
【发布时间】:2019-11-24 00:19:04
【问题描述】:

我的代码包含这样的递归函数:

<?php

$arr = [];

function recursive(&$argument)
{
    if (count($argument) < 10)
    {
        $argument[] = 'foo';
        recursive($argument);
    }
}
recursive($arr);

print_r($arr);

?>

效果很好。但是在我将递归函数转换为 IIFE(立即调用函数表达式)后,错误开始出现,如下所示:

$recursive = (function (&$argument)
{
    if (count($argument) < 10)
    {
        $argument[] = 'foo';
        $recursive($argument);    // line 10
    }
})($arr);

错误是:

注意:未定义变量:第 10 行 php_file_path 中的递归

致命错误:未捕获错误:函数名必须是php_file_path中的字符串:10

堆栈跟踪:

#0 php_file_path(12): {closure}(数组)

#1 {主要}

在第 10 行的 php_file_path 中抛出

我认为可能是函数需要引用自身的变量,所以我添加了关键字use,如下所示。但是结果的错误并没有什么不同,只是未定义变量的通知现在指向第 5 行。

$recursive = (function (&$argument) use ($recursive)    // line 5
{
    if (count($argument) < 10)
    {
        $argument[] = 'foo';
        $recursive($argument);
    }
})($arr);

请注意,代码只是一个示例,只是为了便于说明。

【问题讨论】:

  • 这样不行。 $recursive(会)最终得到调用函数的结果,而不是函数本身。
  • @ggorlen 是的。这只是为了说明的一个例子。我刚刚在我的问题底部添加了该注释。
  • IIFE 中的任何好处都可能特定于您尝试从中移植它的语言,而不是 PHP。只需进行常规递归即可。
  • 目的肯定是不想把函数定义加到全局作用域,只想让事情执行。

标签: php recursion iife


【解决方案1】:

我不清楚你想在这里实现什么,但你可以使用global 语句在函数中定义$recursive 来使你想做的工作:

$arr = array();
($recursive = function (&$argument)
{
    global $recursive;

    if (count($argument) < 10)
    {
        $argument[] = 'foo';
        $recursive($argument);    // line 10
    }
})($arr);
print_r($arr);

输出:

Array
(
    [0] => foo
    [1] => foo
    [2] => foo
    [3] => foo
    [4] => foo
    [5] => foo
    [6] => foo
    [7] => foo
    [8] => foo
    [9] => foo
)

Demo on 3v4l.org

注意在调用之前需要将$arr定义为一个空数组,否则count会失败。如果您不想这样做,则需要在函数中包含if (empty($arr)) 签入。

另请注意,$recursive 可用于此语句之后的其余代码,例如

$arr2 = array();
$recursive($arr2);

这是一种更传统的 PHP 风格:

$recursive = function (&$argument)
{
    global $recursive;

    if (count($argument) < 10)
    {
        $argument[] = 'foo';
        $recursive($argument);    // line 10
    }
};
$arr = array();
$recursive($arr);
print_r($arr);

输出是一样的。 Demo on 3v4l.org

更新

进一步观察,很明显,您可以通过在use 表达式中使用&amp;$recursive 来使用use,而不是global,使其成为引用而不是立即值。例如:

$arr = array();
($recursive = function (&$argument) use (&$recursive)
{
    if (count($argument) < 10)
    {
        $argument[] = 'foo';
        $recursive($argument);    // line 10
    }
})($arr);
print_r($arr);

$recursive = function (&$argument) use (&$recursive)
{
    if (count($argument) < 10)
    {
        $argument[] = 'foo';
        $recursive($argument);    // line 10
    }
};
$arr = array();
$recursive($arr);
print_r($arr);

Demo on 3v4l.org

【讨论】:

  • @IanY。仔细考虑之后,我意识到您可以使用use 而不是global,只需要使用对$recursive 的引用而不是尝试使用立即值。
猜你喜欢
  • 2016-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-18
  • 1970-01-01
  • 2019-09-14
  • 2023-04-05
  • 1970-01-01
相关资源
最近更新 更多