GROOVY预览--闭包

GROOVY预览--闭包,第1张

概述1.Groovy 中的闭包 Java的一些不足可以通过使用groovy的闭包很好的解决,通过下面这个例子来看看使用闭包的优势: 在Java中遍历一个集合的方法是使用迭代,就像下面这样: def acoll = ["Groovy", "Java", "Ruby"] for(Iterator iter = acoll.iterator(); iter.hasNext();){ println iter

1.Groovy 中的闭包

Java的一些不足可以通过使用groovy的闭包很好的解决,通过下面这个例子来看看使用闭包的优势:
在Java中遍历一个集合的方法是使用迭代,就像下面这样:

def acoll = ["Groovy","Java","Ruby"] for(Iterator iter = acoll.iterator(); iter.hasNext();){ println iter.next() }

实际上在 for 循环中并不需要类型声明,因为 Groovy 已经将迭代转变为任何集合的直接成员。在这个示例中,不必获取 Iterator 实例并直接 *** 纵它,可以直接在集合上迭代。而且,通常放在循环构造内的行为(例如 for 循环体中 println)接下来要放在闭包内。在深入之前,先看看如何执行这步 *** 作。

对于上面的代码,可以用更简洁的方式对集合进行迭代,如下所示:

def acoll = ["Groovy","Java","Ruby"] acoll.each{ println it }

请注意,each 直接在 acoll 实例内调用,而 acoll 实例的类型是 ArrayList。在 each 调用之后,引入了一种新的语法 — {,然后是一些代码,然后是 }。由 {} 包围起来的代码块就是闭包。

闭包是可执行的代码块。它们不需要名称,可以在定义之后执行。所以,在上面的示例中,包含输出 it(后面将简单解释 it)的行为的无名闭包将会在 acoll 集合类型中的每个值上被调用。
在较高层面上,{} 中的代码会执行三次,从而生成如图所示的输出。

Groovy Java Ruby

2声明闭包

  迄今为止,我们已经使用了闭包的简单语法:在一个方法调用的后面,放置闭包代码在一对花括号里,闭包的参数和代码通过(->)进行分隔。

  2.1简单的声明方式

  下图中显示了闭包语法的简单方式和一个新的特性,当只有一个参数传递的时候,这个参数是可选的,魔术变量it代替了声明

log='' (1..10).each{counter -> log += counter } println log //12345678910  log='' (1..10).each{log += it } println log //12345678910

  上面两个闭包声明是等价的,注意,不像counter,魔术变量it是不需要声明的。

  2.2 使用赋值的方式声明闭包

  第二种声明闭包的方式是直接将它赋值给一个变量

def printer={ line -> println line}

闭包声明在花括号中,并且赋给了printer变量

通过方法的返回值也是一种闭包的声明方式

def Closure getPrinter(){ return {line -> println line} }

花括号指明构建了一个新的闭包对象,这个对象通过方法的调用返回

  2.3引用一个方法作为闭包

  第三种声明闭包的方式是重用已有的声明:一个方法。方法有一个方法体,可选的返回值,能够接受参数,并且能够被调用,于grooovy的闭包的相似性显而易见,因此groovy可以重用你已经在方法中存在的代码作为一个闭包,引用一个方法作为闭包使用reference.& *** 作符, reference是闭包调用时使用的对象实例,正如一个一般的方法调用使用reference.someMethod().  

上图显示了闭包的调用方法。

下面代码演示了方法闭包的使用

class MethodClosureSample{ int limit MethodClosureSample(int limit){ this.limit = limit } boolean valIDate(String value){ return value.length() <= limit } } MethodClosureSample first = new MethodClosureSample(6) MethodClosureSample second = new MethodClosureSample(4) def firstClosure = first.&valIDate; //方法作为闭包  def words=['Hello','Synvata','I','love','you'] println words.findAll(firstClosure) //[Hello,I,love,you] println words.findAll(second.&valIDate) //[I,you]

3 比较

下面展示了创建和使用闭包的所有方式:使用简单声明、赋值变量和方法闭包

map=['a':1,'b':2,'c':3] /*直接把闭包作为参数传递,这是常用的方式*/ map.each{key,value -> map[key] = value * 2 } println map //[a:2,b:4,c:6] /*将闭包对象赋值给变量doubler*/ doubler={key,value -> map[key] = value * 2 } map.each(doubler) println map //[a:4,b:8,c:12] /*声明一个普通的方法*/ def doubleMethod(entry){ map[entry.key]=entry.value * 2 } /*reference.& *** 作符引用方法作为一个闭包*/ doubler=this.&doubleMethod println doubler //org.codehaus.groovy.runtime.MethodClosure@3fb547 map.each(doubler) println map //[a:8,b:16,c:24]

 4 调用闭包

假设有一个引用x指向一个闭包,我们能通过x.call()来调用闭包,或者简单的x()

def col={println 'Hello,Groovy'} col(); //Hello,Groovy col.call() //Hello,Groovy

现在,我们来试试更复杂的一些东西,从一个方法的内部调用闭包

def benchmark(repeat,Closure worker){ start=System.currentTimeMillis() repeat.times{worker(it)} stop=System.currentTimeMillis() return stop-start } slow=benchmark(1000){ (int)it / 2 } fast=benchmark(1000){ it.intdiv(2) } println slow println fast

在benchmark中我们把闭包作为最后一个参数,这样在调用该方法的时候就可以使用闭包的简单语法声明benchmark(){Closure}。方法参数中Closure声明了闭包的类型,该声明是可选的。repeat.times{worker(it)}根据repeat参数重复的调用闭包,并把当前重复的次数传入闭包


因为不想编写文档,就copY了一下博客园的一篇博文,不敢说是自己写的,说明出处:

http://www.cnblogs.com/jyan/archive/2012/06/01/2529898.html

总结

以上是内存溢出为你收集整理的GROOVY预览--闭包全部内容,希望文章能够帮你解决GROOVY预览--闭包所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1266229.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-08
下一篇 2022-06-08

发表评论

登录后才能评论

评论列表(0条)

保存