这让我很困惑,我似乎无法找到这个问题的答案。清晰简单的说明会很好。
答案 0 :(得分:25)
use statement
在关闭功能创建时捕获变量。
当函数调用时,常规函数参数捕获值。
请注意,我区分了variable
和value
。
function makeAnAdder($leftNum) {
// Notice that *each time* this makeAnAdder function gets called, we
// create and then return a brand new closure function.
$closureFunc = function($rightNum) use ($leftNum) {
return $leftNum + $rightNum;
};
return $closureFunc;
}
$add5to = makeAnAdder(5);
$add7to = makeAnAdder(7);
echo $add5to(10); // 15
echo $add7to(1); // 8
如果有办法检查$add5to
函数的“源代码”,它看起来像这样:
function($rightNum) {
return 5 + $rightNum;
}
我想你可以说闭合函数会记住$leftNum
的值。
我想进一步强调use statement
允许您将reference
维护为变量,而不仅仅是值的副本>变量在某个时刻出现了。澄清我的想法:将变量视为一个小盒子,它可以在任何时刻包含单个值,并且可以更改该值。并且,您可以将另一个变量指向该框,以便您可以更新框中的值,或者读取其中的当前值。
通常,在函数返回后,函数内创建的局部变量不再存在。但是,闭包函数可以保持对该变量的引用,并且即使在函数返回后也会使该局部变量继续存在 - 这是闭包函数的真正功能。它可以让你模拟一个类的某些行为(实例变量),只需要一点点代码。
这是一个更高级的示例,可能需要深入思考才能理解行为的细节。
function makeBankAccount() {
// Each time this makeBankAccount func is called, a new, totally
// independent local variable named $balance is created.
$balance = 0;
// Also, on each call we create 2 new closure functions, $modifyBalance, and $getBalance
// which will hold a reference to the $balance variable even after makeBankAccount returns.
$modifyBalance = function($amount) use (&$balance) {
$balance += $amount;
};
$getBalance = function() use (&$balance) {
return $balance;
};
// return both closure functions.
return ['modifyBalance' => $modifyBalance, 'getBalance' => $getBalance];
}
// Let's prove that bank1 works by adding 5 to the balance by using the first
// function, then using the other function to get the balance
// from the same internal variable.
$bank1 = makeBankAccount();
$bank1['modifyBalance'](5);
echo $bank1['getBalance'](); // 5 - it works.
// Now let's make another bank to prove that it has it's own independent internal $balance variable.
$bank2 = makeBankAccount();
$bank2['modifyBalance'](10);
echo $bank2['getBalance'](); // 10 - as expected. It would have printed 15 if bank2 shared a variable with bank1.
// Let's test bank1 one more time to be sure that bank2 didn't mess with it.
echo $bank1['getBalance'](); // 5 - still 5, as expected.
您可能已经注意到我在此示例中使用了reference operator &
。如果你还没有熟悉它们,只要知道参考文献很难理解。虽然,我希望这篇文章本身最有意义。
答案 1 :(得分:22)
闭包是一个在自己的环境中计算的函数,它有一个或多个绑定变量,可以在调用函数时访问它们。它们来自功能编程世界,其中有许多概念在起作用。闭包就像lambda函数,但在某种意义上它更聪明,它们能够与定义闭包的外部环境中的变量进行交互。
use()关键字让你从函数内部的函数环境中导入变量。要从外部环境导入的变量在闭包函数定义的use子句中指定。默认情况下,它们按值传递。因此,假设该函数没有参数,但您不想使用已有的变量。
$string = "Hello World!";
$closure = function() use ($string) { echo $string; };
当您需要创建一个必须在其他地方用作回调的函数时,这非常有用,并且只能定义参数。 use()关键字让你使用除了作为函数参数传递的变量之外的其他变量。例如,在php.net示例:http://php.net/manual/en/functions.anonymous.php
public function getTotal($tax)
{
$total = 0.00;
$callback =
function ($quantity, $product) use ($tax, &$total)
{
$pricePerItem = constant(__CLASS__ . "::PRICE_" .
strtoupper($product));
$total += ($pricePerItem * $quantity) * ($tax + 1.0);
};
array_walk($this->products, $callback);
return round($total, 2);
}
$ callback必须只有两个参数,因为array_walk只允许那么多:
通常,funcname采用两个参数。数组参数 值是第一个,键/索引第二个。
那我们该怎么办?我们调用use()
来添加不是$ callback范围的其他变量,但是在调用它的环境范围内。