Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
269 views
in Technique[技术] by (71.8m points)

php - What's the difference between closure parameters and the 'use' keyword?

This has got me very confused and I can't seem to find an answer to this question. A clear and simple clarification would be nice.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The use statement captures the variable at the time the closure function is created.

Regular function arguments capture the value when the function is called.

Note that I differentiated between variable and value there.

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

If there were a way to inspect the, um, "source code" of the $add5to function, it would look like this:

function($rightNum) {
    return 5 + $rightNum;
}

I guess you could kinda say the value of $leftNum got remembered by the closure function.

I want to further emphasize that the use statement allows you to maintain a reference to a variable, and not just a copy of the value that the variable had at some point. To clarify my idea: think of a variable as being a little box, which can contain a single value at any instant in time, and that value can be changed. And, you can make another variable point to that box, so that you can update the value in the box, or read the current value in it.

Normally, a local variable that is created within a function ceases to exist after the function returns. But, a closure function can maintain a reference to that variable, and cause that local variable to live on even after the function returns - and this is the true power of closure functions. It lets you mimic certain behaviors of a class (instance variables), with just a tiny bit of code.

Here's a more advanced example, that might take some deep thinking to understand the fine details of the behavior.

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.

You may have noticed I used the reference operator & in this example. If you're not yet familiar with them yet, just know that References are known to be hard to understand. Although, I hope this post mostly makes sense by itself.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...