是否可以具有递归和匿名的PHP函数?这是我尝试使其工作,但未传递函数名称。
$factorial = function( $n ) use ( $factorial ) {
if( $n <= 1 ) return 1;
return $factorial( $n - 1 ) * $n;
};
print $factorial( 5 );
我也知道这是实施阶乘的一种不好方法,这只是一个例子。
print $factorial( 0);
是否可以具有递归和匿名的PHP函数?这是我尝试使其工作,但未传递函数名称。
$factorial = function( $n ) use ( $factorial ) {
if( $n <= 1 ) return 1;
return $factorial( $n - 1 ) * $n;
};
print $factorial( 5 );
我也知道这是实施阶乘的一种不好方法,这只是一个例子。
print $factorial( 0);
Answers:
为了使其正常工作,您需要传递$ factorial作为参考
$factorial = function( $n ) use ( &$factorial ) {
if( $n == 1 ) return 1;
return $factorial( $n - 1 ) * $n;
};
print $factorial( 5 );
&
价值就是价值。的所有内容&
均通过引用提供。“对象”不是PHP5中的值,因此无法分配或传递。您正在处理一个变量,其值为对象引用。与所有变量一样,它可以通过值或引用来捕获,具体取决于是否存在&
。
$factorial
会在调用函数之前进行更改,并且可能会导致异常行为。
我知道这可能不是一个简单的方法,但是我从功能语言中学到了一种称为“修复”的技术。fix
Haskell 的函数通常称为Y组合器,它是最著名的定点组合器之一。
一个不动点是一个函数不变的值:一个函数f的不动点是任何x,使得x = f(x)。定点组合器y是为任何函数f返回固定点的函数。由于y(f)是f的一个固定点,因此我们有y(f)= f(y(f))。
本质上,Y组合器创建一个新函数,该函数接受原始函数的所有参数,再加上一个作为递归函数的附加参数。使用咖喱符号,这是如何工作的更明显。不要在圆括号(f(x,y,...)
)中写参数,而应在函数之后编写:f x y ...
。Y组合器定义为Y f = f (Y f)
;或者,对于递归函数,仅使用一个参数Y f x = f (Y f) x
。
由于PHP不会自动咖喱的功能,这是一个黑客位做出的fix
工作,但我认为这是有趣的。
function fix( $func )
{
return function() use ( $func )
{
$args = func_get_args();
array_unshift( $args, fix($func) );
return call_user_func_array( $func, $args );
};
}
$factorial = function( $func, $n ) {
if ( $n == 1 ) return 1;
return $func( $n - 1 ) * $n;
};
$factorial = fix( $factorial );
print $factorial( 5 );
请注意,这几乎与其他人发布的简单闭包解决方案相同,但是该函数fix
为您创建了闭包。定点组合器比使用闭包稍微复杂一些,但更通用,还有其他用途。尽管闭包方法更适合于PHP(这不是一种功能强大的语言),但最初的问题更多的是练习而不是生产,因此Y组合器是一种可行的方法。
call_user_func_array()
是,圣诞节来得很慢。
call_user_func_array
。
array_unshift( $args, fix($func) );
?Args已经充满了参数,实际的递归是通过call_user_func_array()完成的,那么那行是做什么的?
尽管它不是用于实际用途,但是C级扩展mpyw-junks / phpext-callee提供了匿名递归而不分配变量。
<?php
var_dump((function ($n) {
return $n < 2 ? 1 : $n * callee()($n - 1);
})(5));
// 5! = 5 * 4 * 3 * 2 * 1 = int(120)
您可以在PHP 7.1+中使用Y Combinator,如下所示:
function Y
($le)
{return
(function ($f)
{return
$f($f);
})(function ($f) use ($le)
{return
$le(function ($x) use ($f)
{return
$f($f)($x);
});
});
}
$le =
function ($factorial)
{return
function
($n) use ($factorial)
{return
$n < 2 ? $n
: $n * $factorial($n - 1);
};
};
$factorial = Y($le);
echo $factorial(1) . PHP_EOL; // 1
echo $factorial(2) . PHP_EOL; // 2
echo $factorial(5) . PHP_EOL; // 120
玩它:https : //3v4l.org/7AUn2
源代码来自:https : //github.com/whitephp/the-little-phper/blob/master/src/chapter_9.php
global $factorial
吗?