线上服务咨询
PHP5.3闭包功能和应用程序详细信息
发表时间:2019-07-30 16:40:28
文章来源:沈阳软件开发
标签:网站建设 小程序开发 小程序制作 微信小程序开发 公众号开发 微信公众号开发 网页设计 网站优化 网站排名 网站设计 微信小程序设计 小程序定制 微信小程序定制
浏览次数:0
在我们开始之前,这个例子只是为了澄清观点,而不考虑其他因素,如性能。
“货比三家”
从一个带有以下数组的简单示例开始:
$ nums=array(10,20,30,40);
您需要在数组中查找大于15的项目。因此,在不考虑结束的情况下,我们可以写下这个:
$解析度=阵列(); foreach($ numsas $ n){if($ n> 15){$ res []=$ n; }如果语言本身具有闭包支持,那么它可能是这样写的(Groovy语言)
Def res=nums.findAll {it> 15}或使用Scala语言
Val res=nums过滤器(_> 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解析的详细信息,请参见此处。
目前似乎感觉还不错,那么我们在主题上添加了更多的难度:找到大于15的所有项目,然后乘以2并在范围中添加变量值以返回。
Groovy实现:
Defx=1def res=nums.findAll {it> 15} .collect {it * 2 + x}Scala的实施:
Valx=1valres=numsfilter(_> 15)map(_ * 2 + x)PHP实现:
$ X=1; $ res=array_map(函数($ v)使用($ x){return $ v * 2 + $ x;},array_filter($ nums,function($ v){return $ v> 15;}));就代码大小而言,现在看来PHP与其他语言不同。抛开代码本身的美学,上面的PHP代码还有一个问题。
例如,如果您需要使用数组键而不是值进行比较,该怎么办?是的,上面的代码不起作用。同时,从语法的角度来看,上述代码很难阅读。
回到真相,那么你仍然需要回到旧的想法来解决问题:
$ X=1; $解析度=阵列(); foreach($ numsas $ n){if($ n> 15){$ res []=$ n * 2 + $ x; }这似乎很清楚。但此时你可能会再次感到困惑:“那仍然是一个折腾,不是阵列操作吗?”。
是的,好戏仍然落后。这一次是时候让PHP的一些高级功能出来,以获得似乎有自我伤害倾向的“无聊问题”。
ArrayObject – 对数组的封装
PHP有一个名为SPL的标准库,它包含一个名为ArrayObject的类,它提供“类数组类”的功能,例如
$解析度=newArrayObject(阵列(10,20,30,40)); foreach($ resas $ v){echo'$ vn'; }ArrayObject是一个内置类,因此您可以像其他类操作一样包装它。
Arr - 包上糖衣
现在我们有了ArrayObject和闭包,我们可以开始尝试封装它:
classArrextendsArrayObject {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)){$ res [$ k]=$ v;返回$ res; }好的,一切都准备好了。下面重写的PHP代码将解决上面提到的问题,似乎语法“不多”:
$ res=Arr: make($ nums) - > filter(函数($ k,$ v){return $ v> 15;}) - > map(函数($ k,$ v){return $ v * 2;});
上述代码与传统方式有何不同?首先,他们可以递归并形成链式调用,因此您可以添加更多类似的操作。
同时,您可以通过回调的两个参数来操纵数组的键和项的值 - $ k对应的键和$ v对应的值。这允许我们在闭包中使用键值,而传统的PHP函数array_fliter是不可能的。
另一个好处是更一致的API调用。使用传统的PHP函数操作,第一个参数可能是闭包,数组或多个数组.谁知道呢?
这是Arr类的完整源代码,它包含其他有用的函数(如reduce和walk),但它们的实现类似于代码。
博弈
这个问题实际上很难回答 - 这取决于许多因素,例如代码的上下文和程序员本身。事实上,当我第一次看到PHP闭包实现时,我觉得我很久以前就回到了Java时期,当时我开始使用匿名内置类来实现闭包。当然,尽管可以这样做,但它似乎是一个多余的补充。 PHP闭包本身是正确的,但它的实现和语法让我很困惑。
其他具有闭包功能的语言,可以通过优雅的语法轻松调用闭包。在上面的例子中,在Scala中使用传统循环可以工作,但你会这样写吗?另一方面,有人说上面的主题可以使用PHP闭包来实现,但一般来说你会这样写吗?
可以确定PHP闭包在某些情况下可能变成尖锐的军刀(例如延迟执行和资源调用),但在传统的迭代和数组操作中有点困难。不要气馁,无论如何,编写兼容,干净的代码和API都很重要。
网站建设,小程序开发,小程序制作,微信小程序开发,公众号开发,微信公众号开发,网页设计,网站优化,网站排名,网站设计,微信小程序设计,小程序定制,微信小程序定制