use在Java中什么意思_在PHP中,什么是闭包?为什么要使用“ use”标识符?

我正在检查一些PHP 5.3.0功能,并在网站上遇到了一些看起来很有趣的代码:

public function getTotal($tax)

{

$total = 0.00;

$callback =

/* This line here: */

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);

}

作为匿名函数的例子之一。

有人知道吗? 有文件吗? 而且看起来很邪恶,应该使用它吗?

#1楼

一个简单的答案。

function ($quantity) use ($tax, &$total) { .. };

闭包是分配给变量的函数,因此您可以传递它

闭包是一个单独的命名空间,通常,您不能访问此命名空间之外定义的变量。 使用关键字:

use允许您访问(使用)闭包内部的后续变量。

使用是早期绑定。 这意味着在定义闭包时将复制变量值。 因此,在闭包内部修改$tax不会产生外部影响,除非它像对象一样是指针。

您可以像使用&$total一样将变量作为指针传递。 这样,修改$total的值确实具有外部效果,原始变量的值会更改。

在闭包内部定义的变量也不能从闭包外部访问。

闭合和功能具有相同的速度。 是的,您可以在所有脚本中使用它们。

正如@Mytskine 指出的那样 ,最好的深入解释可能是针对闭包的RFC 。 (为此投票给他。)

#2楼

这就是PHP表示闭包的方式 。 这根本不是邪恶的,实际上它是强大而有用的。

基本上,这意味着您允许匿名函数在其作用域之外“捕获”局部变量(在本例中$tax和对$total的引用)并保留其值(或在$total的情况下,引用为( $total本身)作为匿名函数本身内的状态。

#3楼

封口很漂亮! 它们解决了匿名函数带来的许多问题,并使真正优雅的代码成为可能(至少在我们谈论php时)。

javascript程序员一直在使用闭包,有时甚至不知道闭包,因为绑定变量未明确定义-这就是php中“ use”的含义。

有比以上示例更好的真实示例。 假设您必须按子值对多维数组进行排序,但是键会发生变化。

function generateComparisonFunctionForKey($key) {

return function ($left, $right) use ($key) {

if ($left[$key] == $right[$key])

return 0;

else

return ($left[$key] < $right[$key]) ? -1 : 1;

};

}

$myArray = array(

array('name' => 'Alex', 'age' => 70),

array('name' => 'Enrico', 'age' => 25)

);

$sortByName = generateComparisonFunctionForKey('name');

$sortByAge = generateComparisonFunctionForKey('age');

usort($myArray, $sortByName);

usort($myArray, $sortByAge);

?>

警告:未经测试的代码(我没有在atm上安装php5.3),但它看起来应该像这样。

有一个缺点:如果您面对闭包的话,许多php开发人员可能会有些无奈。

为了进一步了解闭包的好处,我再举一个例子-这次使用javascript。 问题之一是范围和浏览器固有的异步性。 特别是关于window.setTimeout(); (或-interval)。 因此,您将一个函数传递给setTimeout,但实际上不能给出任何参数,因为提供参数会执行代码!

function getFunctionTextInASecond(value) {

return function () {

document.getElementsByName('body')[0].innerHTML = value; // "value" is the bound variable!

}

}

var textToDisplay = prompt('text to show in a second', 'foo bar');

// this returns a function that sets the bodys innerHTML to the prompted value

var myFunction = getFunctionTextInASecond(textToDisplay);

window.setTimeout(myFunction, 1000);

myFunction返回带有某种预定义参数的函数!

老实说,自5.3起,我更喜欢php和匿名函数/闭包。 命名空间可能更重要, 但它们却不那么性感 。

#4楼

Zupa在解释“使用”的闭包以及EarlyBinding和引用“已使用”变量之间的区别方面做得非常出色。

因此,我制作了一个带有早期绑定变量(=复制)的代码示例:

$a = 1;

$b = 2;

$closureExampleEarlyBinding = function() use ($a, $b){

$a++;

$b++;

echo "Inside \$closureExampleEarlyBinding() \$a = ".$a."
";

echo "Inside \$closureExampleEarlyBinding() \$b = ".$b."
";

};

echo "Before executing \$closureExampleEarlyBinding() \$a = ".$a."
";

echo "Before executing \$closureExampleEarlyBinding() \$b = ".$b."
";

$closureExampleEarlyBinding();

echo "After executing \$closureExampleEarlyBinding() \$a = ".$a."
";

echo "After executing \$closureExampleEarlyBinding() \$b = ".$b."
";

/* this will output:

Before executing $closureExampleEarlyBinding() $a = 1

Before executing $closureExampleEarlyBinding() $b = 2

Inside $closureExampleEarlyBinding() $a = 2

Inside $closureExampleEarlyBinding() $b = 3

After executing $closureExampleEarlyBinding() $a = 1

After executing $closureExampleEarlyBinding() $b = 2

*/

?>

引用变量的示例(注意变量前的“&”字符);

$a = 1;

$b = 2;

$closureExampleReferencing = function() use (&$a, &$b){

$a++;

$b++;

echo "Inside \$closureExampleReferencing() \$a = ".$a."
";

echo "Inside \$closureExampleReferencing() \$b = ".$b."
";

};

echo "Before executing \$closureExampleReferencing() \$a = ".$a."
";

echo "Before executing \$closureExampleReferencing() \$b = ".$b."
";

$closureExampleReferencing();

echo "After executing \$closureExampleReferencing() \$a = ".$a."
";

echo "After executing \$closureExampleReferencing() \$b = ".$b."
";

/* this will output:

Before executing $closureExampleReferencing() $a = 1

Before executing $closureExampleReferencing() $b = 2

Inside $closureExampleReferencing() $a = 2

Inside $closureExampleReferencing() $b = 3

After executing $closureExampleReferencing() $a = 2

After executing $closureExampleReferencing() $b = 3

*/

?>

#5楼

function () use () {}类似于PHP的闭包。

如果不use ,函数将无法访问父作用域变量

$s = "hello";

$f = function () {

echo $s;

};

$f(); // Notice: Undefined variable: s

$s = "hello";

$f = function () use ($s) {

echo $s;

};

$f(); // hello

use变量的值来自定义函数时的值,而不是调用时的值

$s = "hello";

$f = function () use ($s) {

echo $s;

};

$s = "how are you?";

$f(); // hello

与&一起use变量按引用

$s = "hello";

$f = function () use (&$s) {

echo $s;

};

$s = "how are you?";

$f(); // how are you?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值