软件的信雅达

原创 Groovy探索之闭包 四收藏

新一篇: Groovy探索之Builder 四

                            Groovy探索之闭包 四
 
前面我都有数次提到过,说闭包较之于方法或者内部类都显得格外的灵活,前面的《Groovy探索之闭包》也都是围绕着闭包灵活的这一特性来阐述的。今天将要提到的是闭包灵活性的另外一个方面——curry方法。
为什么说闭包的curry方法是闭包灵活性的又一个方面,我不想泛泛而谈,下面还是从几个例子说起。
假设我们有一个方法来计算成方:
   
    defstatic cal(int x,int y)
    {
       return x**y
    }
现在,我们要对如下的数组做平方运算:
 
     int[] nums = [1,2,3,6,8] asint[]
 
对于Java语言的解决方案是增加一个计算平方的方法,如下:
   
    defstatic sqr(int x)
    {
       cal(x,2)
}
 
则上述的数组可以做如下的运算:
     nums.each{
        println sqr(it)
 }
 
这段代码再往下,我们要对下面的数组做立方运算:
     
     int[] num1s = [1,5,4,6,7] asint[]
   
 
则我们又要增加一个计算立方的方法:
    defstatic cube(int x)
    {
       cal(x,3)
}
 
可以看到,由于需求的增加,我们要不断的增加方法来满足新的需求。这种情况,不论是对于公用代码的提供者,还是公用代码的使用者,都是相当麻烦的。
如果使用闭包来解决这个问题,则公用代码的提供者只需要提供一个方法,即:
    defstatic cal = {
       int x,int y ->
           y**x
}
 
而客户端在使用这个闭包,就成了下面的样子:
     
     def sqr = cal.curry(2)
     
     int[] nums = [1,2,3,6,8] asint[]
     nums.each{
        println sqr(it)
     }
     
     println'--------------------------'
     
     def cube = cal.curry(3)
     
     int[] num1s = [1,5,4,6,7] asint[]
     num1s.each{
        println cube(it)
        
 }
 
可以看到,这种对闭包进行curry运算的解决方案,的确是要比上面的解决方案简单一些,而且更加方便和灵活得多。
上面的代码的运行结果为:
1
4
9
36
64
--------------------------
1
125
64
216
343
 
 
经过了上面的介绍,你可能会说,闭包的curry方法非常方便,我喜欢使用它。但是,我也有问题,就是遗留的Java语言工具类,我可以使用闭包的curry方法吗?
当然可以,我们还是来看看实际的例子吧。
下面是我们的Java类:
 
publicclass Tools {
   
    publicstaticint cal(int x,int y)
    {
       return (int)Math.pow(x, y);
    }
   
 
}
 
现在我们在Groovy语言中使用它:
 
       def cal = Tools.&cal;
      
        def sqr = cal.curry(2)
        
        int[] nums = [1,2,3,6,8] asint[]
        nums.each{
            println sqr(it)
        }
        
        println'--------------------------'
        
        def cube = cal.curry(3)
        
        int[] num1s = [1,5,4,6,7] asint[]
        num1s.each{
            println cube(it)
            
     }
 
使的,在Groovy语言中,“.&”运算符就可以将一个方法转变为一个闭包,如上面的:
def cal = Tools.&cal;
 
然后,我们就可以对cal对象进行闭包的任何操作。
 
 
 

发表于 @ 2008年05月14日 08:07:47|评论(loading...)|编辑

旧一篇: Groovy Tip 13 “.&”运算符

评论

#ttkk1024 发表于2008-05-14 10:04:13  IP: 218.26.96.*
虽然对这个不熟悉,但对你的敬业的精神表示敬佩!
#johnnyjian 发表于2008-05-14 11:37:31  IP: 125.120.10.*
有一个问题:“.&”操作符是不是在原来的方法上新建一个wrapper的Closure对象,然后这个闭包会调用原来的方法?
好像闭包就是一个Closure的对象吧,是这样吗?
#hivon 发表于2008-05-14 13:13:43  IP: 61.57.242.*
我感觉您的理解没有问题。所以的闭包放在JVM上来说都是一个Object。
def clo = {x->......}这种形式的声明,在JVM上是一个类,里面有一个function,function做实际的动作。
而“.&”式的声明,在JVM上也是一个类,里面有一个function,function的动作引用另外一个对象的function。
以上都是我的理解。但没有找到有文章来支持。
#johnnyjian 发表于2008-05-14 15:15:17  IP: 125.120.10.*
我觉得只要反编译一下Groovy生成的class文件,就一目了然了
#hivon 发表于2008-05-14 15:37:48  IP: 61.57.242.*
说得也是,Groovy语言生成的class,反编译以后可读性很差,我不太爱做反编译。
#BlackAngel_can 发表于2008-05-17 10:38:50  IP: 222.247.91.*
第一次接触闭包是在 javascript 里面,不知道这里是不是有所不同 ?
#johnnyjian 发表于2008-05-17 12:19:21  IP: 60.12.143.*
to BlackAngel_can:
基本概念是一样的,但是groovy的闭包的写法比js的要简单一些,js里面是
function() {...} 或者 function(x) {...}
而groovy里则是
{...} 或者 { x -> ...}
#wuheng66888 发表于2008-05-18 17:15:54  IP: 221.205.31.*
向您推荐 skinfeature 界面换肤组件
http://www.skinui.com
发表评论  


当前用户设置只有注册用户才能发表评论。如果你没有登录,请点击登录
Csdn Blog version 3.1a
Copyright © hivon