首页 > 解决方案 > 为什么我应该将我的函数分配给一个变量?

问题描述

在阅读 php.net 上的匿名函数条目并查看提供的示例时,我遇到了本节,其中提到了这些函数的第二个用例:

闭包也可以用作变量的值。

我想知道为什么要为变量分配方法?我想在这里理解的是这种方法的优势是什么:

$greet = function($name)
{
    echo "Hello $name";
};

$greet('World');
$greet('PHP');

在这样的一块:

function greet($name) 
{
    echo "Hello $name";
}
greet('World');
greet('PHP');

这证明了它的合理性?它只是编写一段代码的另一种方式吗?或者,在某些情况下,在更高级的设计中,它会为更具描述性的代码库留出空间?

标签: phpanonymous-function

解决方案


这是一个很好的问题。匿名函数的问题是它们通常应该是匿名的。当您将它们分配给一个变量时,您给它们一个名称,这违背了目的。

在一个简单的示例中,它们的工作方式与命名函数相同:

function named($a) {
    echo 'This is '.$a;
}

$unnamed = function ($a) {
    echo 'This is '.$a;
};

function caller($callee, string $name) {
    $callee($name);
}

caller('named', 'named');
caller($unnamed, 'unnamed');

唯一的区别是类型$callee一次是字符串,一次是函数。

区别:

想象一下,当您想将当前范围捕获到一个函数中并将其传递给另一个函数以作为回调执行时,您有一个场景。

$v1 = 2;
$a = function() use($v1) { return $v1; };
// or 
$a = fn() => $v1;
$v1 = 4;

function named($callback) {
    $v1 = 3;
    echo $callback();
}

named($a); //output is 2

对于普通函数,您必须将值作为参数传递给函数。在调用函数时,值已更改,这意味着您需要在定义函数时自己捕获该值。

您可以将闭包分配给变量的事实并不意味着您必须这样做。这意味着该函数可以作为一等公民传递。

例如,考虑这段代码,它捕获B类中的私有属性并将其在闭包内传递给A类:

class A {
    private $someVar = 'Hello world!';

    public function __construct($callback) {
        $callback();
    }
}

class B {
    private $someVar = 'Bogus!';

    public function createCallback() {
        return function () {
            echo $this->someVar;
        };
    }
}

$b = new B();
new A($b->createCallback()); // echo Bogus!

推荐阅读