在 php 7.4 中重写一个匿名函数
Rewriting an anonymous function in php 7.4
有如下匿名递归函数:
$f = function($n) use (&$f) {
return ($n == 1) ? 1 : $n * $f($n - 1);
};
echo $f(5); // 120
我尝试重写到 7.4 版本,但出现错误,请告诉我我缺少什么?
$f = fn($n) => ($n == 1) ? 1 : $n * $f($n - 1);
echo $f(5);
Notice: Undefined variable: f
Fatal error: Uncaught Error: Function name must be a string
我认为您不能将函数重写为箭头函数。
箭头函数将在创建函数时按值 捕获任何外部变量的值。但是 $f
在创建函数并分配变量之前不会有值。
原始匿名函数通过使用 use (&$f)
而不是 use ($f)
捕获对变量的引用来解决此问题。这样,它将能够使用赋值产生的变量的更新值。
正如 Barmar 所说,您不能在外部范围内使用 $f
,因为当隐式绑定发生时,$f
仍未定义。
没有什么能阻止您稍后将其作为参数传递。
$f = fn($f, $n) => $n == 1 ? 1 : $n * $f($f, $n - 1);
echo $f($f, 5); // 120
箭头函数的工作方式是,在定义期间,它们将使用外部作用域变量的按值绑定。
As already mentioned, arrow functions use by-value variable binding. This is roughly equivalent to performing a use($x)
for every variable $x
used inside the arrow function. - https://wiki.php.net/rfc/arrow_functions_v2
闭包对变量 $f
的赋值发生在闭包定义之后,而变量 $f
在它之前是未定义的。
据我所知,在定义箭头函数时没有任何机制可以通过引用进行绑定。
我想我刚刚找到了 $GLOBALS
的合法(不是?)用途之一
$f = fn ($n) =>($n == 1) ? 1 : $n * $GLOBALS['f']($n - 1);
echo $f(5); // 120
旁注: 如果 $n < 1
怎么办?
作为@scorpion35 所说的细微变化,您还可以应用柯里化:
$f = fn($f) => fn($x) => $x <= 1
? $x
: $f($f)($x-1) * $x;
$factorial = $f($f);
$factorial(7); //5040
有如下匿名递归函数:
$f = function($n) use (&$f) {
return ($n == 1) ? 1 : $n * $f($n - 1);
};
echo $f(5); // 120
我尝试重写到 7.4 版本,但出现错误,请告诉我我缺少什么?
$f = fn($n) => ($n == 1) ? 1 : $n * $f($n - 1);
echo $f(5);
Notice: Undefined variable: f
Fatal error: Uncaught Error: Function name must be a string
我认为您不能将函数重写为箭头函数。
箭头函数将在创建函数时按值 捕获任何外部变量的值。但是 $f
在创建函数并分配变量之前不会有值。
原始匿名函数通过使用 use (&$f)
而不是 use ($f)
捕获对变量的引用来解决此问题。这样,它将能够使用赋值产生的变量的更新值。
正如 Barmar 所说,您不能在外部范围内使用 $f
,因为当隐式绑定发生时,$f
仍未定义。
没有什么能阻止您稍后将其作为参数传递。
$f = fn($f, $n) => $n == 1 ? 1 : $n * $f($f, $n - 1);
echo $f($f, 5); // 120
箭头函数的工作方式是,在定义期间,它们将使用外部作用域变量的按值绑定。
As already mentioned, arrow functions use by-value variable binding. This is roughly equivalent to performing a
use($x)
for every variable$x
used inside the arrow function. - https://wiki.php.net/rfc/arrow_functions_v2
闭包对变量 $f
的赋值发生在闭包定义之后,而变量 $f
在它之前是未定义的。
据我所知,在定义箭头函数时没有任何机制可以通过引用进行绑定。
我想我刚刚找到了 $GLOBALS
$f = fn ($n) =>($n == 1) ? 1 : $n * $GLOBALS['f']($n - 1);
echo $f(5); // 120
旁注: 如果 $n < 1
怎么办?
作为@scorpion35 所说的细微变化,您还可以应用柯里化:
$f = fn($f) => fn($x) => $x <= 1
? $x
: $f($f)($x-1) * $x;
$factorial = $f($f);
$factorial(7); //5040