PHP中实现Currying(柯里化)遇递归调用问题求助
解决PHP柯里化函数中递归调用的未定义变量问题
你的代码报错是因为内部匿名函数无法访问外层的$curried变量——PHP闭包默认采用值传递,且你在定义内部闭包时,$curried还未完成赋值,导致递归调用时变量未定义。
修正后的可运行代码
function test(callable $fn){ $reflection = new ReflectionFunction($fn); $requiredArgs = count($reflection->getParameters()); // 先声明变量,确保内部闭包可引用 $curried = null; $curried = function(...$currArgs) use(&$curried, $requiredArgs, $fn){ $totalArgs = count($currArgs); // 已传入足够参数,执行原函数 if($totalArgs >= $requiredArgs){ return $fn(...array_slice($currArgs, 0, $requiredArgs)); } // 参数不足,返回新的闭包收集更多参数 return function(...$newArgs) use(&$curried, $currArgs){ return $curried(...array_merge($currArgs, $newArgs)); }; }; return $curried; } // 测试 $c = test(fn($x, $y, $z) => $x + $y + $z); echo $c(10)(20,30); // 输出60
关键修正点说明
- 引用传递
&$curried:
内部闭包需要通过引用访问$curried变量,这样才能在递归调用时获取到最新的柯里化函数实例,而不是初始的null值。 - 提前声明
$curried变量:
先初始化$curried = null,再赋值闭包,确保变量在闭包定义时已存在,避免“变量未定义”的错误。 - 参数兼容优化:
将判断条件改为$totalArgs >= $requiredArgs,并用array_slice截取所需参数,即使传入超过需求的参数也能正常执行。
内容的提问来源于stack exchange,提问作者Vivek
相关产品推荐
相关产品推荐

