快捷搜索:  as  2018  FtCWSyGV  С˵  test  xxx  Ψһ  w3viyKQx

澳门新葡亰app是真的吗_龟发之家论坛



09年7月宣布的PHP 5.3 版本带来了很多新的特点,, 此中对照惹眼的特点之一便是支持了闭包;那么今后,我们也可以和那帮写 Ruby、Javascript 等等“高科技说话的家伙们一样,写出异常酷的代码吗?呃,着实大年夜部分环境下是可以的,而有些方面照样令人异常的困扰,下面逐步道来。

很多说话的都供给了异常优雅和漂亮的操作数组的措施。鄙人面的例子中,会应用PHP5.3闭包特点以及其他说话供给的闭包功能,用于展示若何“客不雅的操作迭代数组。

译注:原文作者对照火星,我不懂得 Groovy 以及 Scala说话,以是这里我加上 Javascript 的实现。

在开始之前先阐明下,本例子仅仅是说明不雅点,并没有斟酌机能等其他方面的身分。

;

“货比三家

用个简单的例子开始,有下面个数组:

$nums = array(10, 20, 30, 40);

必要找出数组中大年夜于 15 的项。那么,不斟酌闭包的环境下,我们或许会这样写:

$res=;array(); ;

foreach($nu澳门新葡亰app是真的吗msas$n);{; ;if($n>;15);{$res[];=;$n ;

} ;};

假如说话本身有闭包支持的,那么或许会这样写(Groovy 说话)

def res = nums.findAll { it > 15 }或者应用 Scala 说话

val res = nums filter (_ > 15)译注:Javascript 1.6 的话会是如下

var res = nums.filter(function(c){return c > 15});

由于轮回操作已被抽象起来,以是可以看到 Groovy 、Scala (以及 Javascript) 都很漂亮得用一行就可以搞定。

当然,假如应用 PHP5.3 的闭包,也可以做到

$res = array_filter($nums, function($v) { return $v > 15; });

PHP 在这方面应用了比 Scala 更多的字符,但比较先前的例子,它更简短并且能更好得涉猎。

顺便说下,上面的 PHP 代码实际上是应用了 Lambda 解析式,并不是个真正的闭包,这个 并不是我们今朝关注的重点。具体阐述 PHP 闭包以及 Lambda 解析式的资料,可以参考这里。澳门新葡亰app是真的吗

今朝看来感到都还不错,那么我们再的题目增添点难度:找到所有大年夜于 15 的项, 然后乘以 2 再加上感化域中的的某个变量值今后再返回。

Groovy 的实现:

def;x;=;1def; ;

res;=;nums;.findAll;{;it;>;15};.collect;{;it;*;2+;x;};

Scala 的实现:

val;x;=; ;

1val;res;=;nums;filter;(_;>;15);map;(_;*;2+;x);

PHP的实现:

$x=;1; ;

$res=;array_map( ;function($v);use($x);{; ;

return$v*;2;+;$x},;;;array_filter($nums, ;

function($v);{;return$v>;15;;}) ;); ;

光从代码量方面,现在看起来 PHP 与其他说话有进出了。先抛开代码字面上本身 的审美不谈,上面的 PHP 代码还有个额外的问题。

例如,假如必要应用数组的键而非值作对照,怎么办?是的,上面的代码就办不到了。同时,从语法角度上说,上面的代码异常难以涉猎。

返璞归真,这时照样得返回老土的思路去办理问题:

$x=;1; ;

$res=;array(); ;foreach($numsas$n);{ ;

if($n>;15);{ ;$res[];=;$n*;2;+;$x ;

} ;};

这样看起来又很清楚了。但这个时刻你或许又会迷惑了:“那还瞎折腾啥,这不便是个数组操作吗?。

是的,好戏还在背面。这个时刻该让 PHP 的某些高档特点出场,来搞定这看似有自残倾向 的“无聊问题。

ArrayObject – 对数组的封装

PHP 有个称作 SPL 的标准库,此中包孕了个叫做 ArrayObject 的类,它能供给“像数组一 样操作类的功能,例如

$res=;newArrayObject(array(10,;20,;30,;40)); ;

foreach($resas$v);{ ;echo"$vn" ;

};

ArrayObject 是个内置的类,以是你可以像其他类类操作一样封装它。

Arr - 包上糖衣

既然我们已经有了 ArrayObject 以及闭包这些特点,我们就可以开始考试测验封装它:

classArr;extendsArrayObject{;;;

staticfunctionmake($array);;;;{ ;returnnewself($array); ;

};;;;functionmap($func) ;{;;;;;;

$res=;newself(); ;foreach($thisas$k=>;$v);{; ;

$res[$k];=;$func($k,;$v); ;}return$res} ;

functionfilter($func);;;;{ ;$res=;newself(); ;

foreach($thisas$k=>;$v);{ ;if($func($k,;$v))澳门新葡亰app是真的吗;{; ;

$res[$k];=;$v ;} ;

} ;return$res ;

} ;};

好了,万事俱备。下面重写的 PHP 代码就可以办理上面提到的问题,并且看起来语法上“差 不多了:

$res = Arr::make($nums);->filter(function($k, $v)

{ return $v > 15; });->map(function($k, $v)

{ return $v * 2; });

上面的代码与传统要领有何不合呢?首先,它们可以递归并形成感化链式的调用,是以可以 添加更多的类似操作。

同时,可以经由过程回调的两个参数分手操作数组的键以及值其项 - $k 对应键以及 $v 对应值 。这使得我们可以在闭包中应用键值,这在传统的 PHP 函数 array_fliter 中是无法实现的。

别的个带来的额外好处便是加倍同等 API 调用。应用传统的 PHP 函数操作,它们有可能第一个参数是个闭包,或者是个数组,抑或是多个数组…总之谁知道呢?

这里是 Arr 类的完备源代码,还包孕了其他有用的函数(类似 reduce 以及 walk),着实它 们的实实际在要领和代码类似。

博弈

这个问题着实很难回答 - 这必要根据代码的高低文以及法度榜样员自身等浩繁身分抉择。着实 ,当我第一眼望见 PHP 的闭包实现时,我感到彷佛回到了那好久曩昔的 Java 时期,当时 我在开始应用匿名内置类(anonymous inner classes)来实现闭包。当然,这虽然可以做到, 但看起来其实是些枝节横生。PHP 闭包本身是没错,只是它的实现以及语法让我认为异常的利诱。

其他具有闭包特点的说话,它们可以异常方便的调用闭包并同时具有优雅的语法。在上面的例子 中,在 Scala 中应用传统的轮回也可以事情,但你会这样写吗?而从另个方面,那么有人 说上面这个题目应用 PHP 的闭包也可以实现,但一样平常环境下你会这样写吗?

可以确定,PHP 闭包在些环境下可以成为锐利的军刀(例如延时履行以及资本调用方面), 但在传统的迭代以及数组操作眼前就显得有些尴尬。不要气馁不管怎么样, 返璞归真编写具有兼容性的澳门新葡亰app是真的吗、清爽的代码以及 API 是最紧张的。

停止语

像所有后来加上的语法特点一样(记得昔时 Java 的 Generics 特点不?以及前几年的 PHP OOP 特点),它们都必要光阴磨合以及终极稳定下来。跟着 PHP5.3 以致将来的 PHP6 徐徐遍及,越来越多的技术和特点信托在不远的将来徐徐的被智慧的法度榜样员掘客出来。

回到最初文章开首那个题目,比较

$res = Arr::make($nums)

->filter(function($k, $v) { return $v > 15; })

->map(function($k, $v) { return $v * 2; });

以及

val res = nums filter (_ > 15) map (_ * 2)

两者之间的差别。归根结底它们仅是澳门新葡亰app是真的吗语法而已,本色上都是殊途同归办理了同个问题。法度榜样 说话的利用特点不合,自然孰优孰劣也就无从对照。

您可能还会对下面的文章感兴趣: