什么是 PHP Lambda(匿名函数) 和 Closures(闭包)?
目录
什么是 Lambda(匿名函数)?
什么是Closures(闭包)?
现实生活中的用法
结论
Lambda 和 Closures 是 PHP 在 5.3 版发布后相对较新的新增功能。两者都提供了一些新功能,并能够重构旧代码,使其更简洁、更直观。但是,我认为许多开发人员不知道 Lambda 和闭包,或者对它们的实际作用感到困惑。
在这篇文章中,我将解释 Lambda 和闭包,给你一些示例代码来展示它们的用法,并给你一个它们在现代 PHP 中的实际示例,向你展示它们在现代 PHP 中的流行程度。
什么是 Lambda?
Lambda 是一个匿名函数,可以分配给变量或作为参数传递给另一个函数。如果你熟悉其他编程语言,如Javascript或Ruby,你会非常熟悉匿名函数。
匿名函数
匿名函数只是一个没有名称的函数。
例如,要创建一个常规函数,您可以编写如下内容:
// Regular function
function greeting()
{
return "Hello world";
}
然后,您可以像这样简单地调用此函数:
echo greeting();
// Returns "Hello world"
匿名函数没有名称,因此您可以像这样定义它:
// Anonymous function
function ()
{
return "Hello world";
}
使用Lambdas
由于函数没有名称,因此不能像常规函数一样调用它。相反,您必须将其分配给变量或将其作为参数传递给另一个函数。
// Anonymous function
// assigned to variable
$greeting = function () {
return "Hello world";
}
// Call function
echo $greeting();
// Returns "Hello world"
为了使用匿名函数,我们将其分配给一个变量,然后将该变量作为函数调用。
您也可以将该函数传递给另一个函数,如下所示:
// Pass Lambda to function
function shout($message)
{
echo $message();
}
// Call function
shout(function () {
return "Hello world";
});
为什么要使用 Lambda?
Lambda 很有用,因为它们是一次性可以使用的函数。通常,您需要一个函数来完成工作,但是将其置于全局范围内甚至将其作为代码的一部分提供是没有意义的。与其使用一次函数然后闲置,不如改用 Lambda。
当然,您已经在 PHP 中使用 create_function 函数已有一段时间了。这基本上做同样的工作。
// Use create_function
$greeting = create_function('echo "Hello World!";');
// Call function
$greeting();
什么是闭包?
闭包本质上与 Lambda 相同,除了它可以访问创建范围之外的变量。
例如:
// Create a user
$user = "Philip";
// Create a Closure
$greeting = function () use ($user) {
echo "Hello $user";
};
// Greet the user
$greeting(); // Returns "Hello Philip"
正如你在上面看到的,闭包能够访问$user变量。因为它是在闭包函数定义的 use 子句中声明的。
如果要更改闭包中的$user变量,则不会影响原始变量。要更新原始变量,我们可以附加一个 & 符号。变量前的 & 符号表示这是一个引用,因此原始变量也会更新。
例如:
// Set counter
$i = 0;
// Increase counter within the scope
// of the function
$closure = function () use ($i) {
$i++;
};
// Run the function
$closure();
// The global count hasn't changed
echo $i; // Returns 0
// Reset count
$i = 0;
// Increase counter within the scope
// of the function but pass it as a reference
$closure = function () use (&$i) {
$i++;
};
// Run the function
$closure();
// The global count has increased
echo $i; // Returns 1
当使用接受回调函数(如array_map、array_filter、array_reduce或array_walk)的 PHP 函数时,闭包也很有用。
array_walk函数获取一个数组并通过回调函数运行它。
// An array of names
$users = ["John", "Jane", "Sally", "Philip"];
// Pass the array to array_walk
array_walk($users, function ($name) {
echo "Hello $name<br>";
});
// Returns
// -> Hello John
// -> Hello Jane
// -> ..
同样,您可以使用 use 子句访问闭包范围之外的变量:
// Set a multiplier
$multiplier = 3;
// Create a list of numbers
$numbers = [1, 2, 3, 4];
// Use array_walk to iterate
// through the list and multiply
array_walk($numbers, function ($number) use ($multiplier) {
echo $number * $multiplier;
});
在上面的例子中,创建一个函数来将两个数字相乘可能没有意义。如果你要创建函数来完成这样的工作,那么过一会儿回到代码,你可能会想为什么你费心创建一个全局可访问的函数只使用一次?通过使用 Closure 作为回调,我们可以使用该函数一次,然后忘记它。
现实生活中的用法
因此,我们已经确定 Lambda 和闭包是匿名函数,可以用作丢弃的功能位,这些功能不会污染全局命名空间,并且非常适合用作回调的一部分。
使用这些类型函数的一个流行示例是在现代框架内路由请求。例如,Laravel允许您执行以下操作:
Route::get("user/(:any)", function ($name) {
return "Hello " . $name;
});
上面的代码只是匹配像 /user/philip 这样的 URL 并返回一个问候语。
这是一个非常基本的例子,但它强调了如何在非常有用的情况下使用闭包。
结论
所以希望这是对 Lambda 和闭包的一个很好的解释。
如果你是一个新手程序员,Lambdas和闭包似乎是两个非常深奥的计算机科学术语。但是,实际上它一点也不复杂。Lambda 和闭包都只是匿名函数,它们对一次性有用,或者在定义函数没有意义的情况下。
Lambdas和Closures对PHP来说是相当新的,它们与其他语言的用法并不完全相同。如果你熟悉Javascript,你会看到匿名函数被大量使用。特别是,你会在jQuery中看到很多很好的例子。一旦你能够识别出模式,它就会使阅读代码变得容易得多,因为你不仅了解发生了什么,而且还理解为什么一开始就这样写它,以及开发人员试图通过她的决定实现什么。
评论 (0)