原文件:http://groovy.codehaus.org/Tutorial+2+-+Code+as+data%2C+or+closures
译者:puras
1.闭包
有一件事让Groovy与其他大多数的编译语言不同,就是你可以为第一类对象创建方法.你可以定义一个代码块,并像字符串或整数一下赋给它.查看下面的代码:
square = { it * it }
在大括号中的表达式"it * it"告诉Groovy编译器将表达式看成一段代码.在软件世界中,称之为"闭包".在这个例子中,"it"是提供给方法的值的引用.之后编译后的方法像上面一样赋给变量"square".所以,现在我们可以像这样来做些事:
square(9)
得到的值为81.
这不是非常有趣的,直到我们发现我们可以为"square"方法传一些值.这有一些内建的方法为这个方法提供一个参数.一个例子就是数组的"collect"方法.尝试这样做:
[ 1, 2, 3, 4 ].collect(square)
这个表达式说,使用值1, 2, 3和4创建一个数组,之后调用"collect"方法,将我们上面定义的闭包传进去.执行这个"collect"方法遍历数组中的每一个条目,在这些条目上调用这个闭包,之后将结果放到一个新的数组里,结果为:
[ 1, 4, 9, 16 ]
对于多数的方法,你可以当作参数一样调用闭包,查看Groovy GDK documentation.
默认的,闭包将一个参数称为"it",你同样可以使用名字参数来创建闭包.例如Map.each()方法,可以为闭包提供两个变量,将它们分别绑定到Key和关联的值上:
printMapClosure = { key, value -> println key + "=" + value } [ "yue" : "wu", "lane" : "burks", "sudha" : "saseethiaseeleethialeselan" ].each(printMapClosure)
结果:
yue=wu lane=burks sudha=saseethiaseeleethialeselan
2.闭包的例子
这里有一些闭包的例子.第一个展示了两件事.第一,闭包与它自己之外的变量相结合.更确切的说,这个闭包的目的是将数组orderParts中存储的各部分,有序的结合到一起,添加(或附加)给变量fullString.变量fullString没有在闭包中.第二件事是这个例子中不同的是闭包是"匿名"的,意思是它不需要提供一个名字,并且在each方法中指定的地方被调用.
fullString = "" orderParts = ["BUY", 200, "Hot Dogs", "1"] orderParts.each { fullString += it + " " } println fullString
你或许能猜到它输出的是什么.
下一个例子是另一个匿名闭包,这里,将计算存储中Map中的值.
myMap = ["asdf": 1 , "qwer" : 2, "sdfg" : 10] result = 0 myMap.keySet().each( { result+= myMap[it] } ) println result
3.文件处理
从文件中读取数据,是非常简单的.首先创建一个文本文件,并将其命名为"myfile.txt".它意味着什么并不要紧,随便的输入一些文字,并把它保存在你的C盘下的temp目录里.之后在groovyConsole里输入下面的代码:
yFileDirectory = "C:\\temp\\" myFileName = "myfile.txt" myFile = new File(myFileDirectory + myFileName) printFileLine = { println "File line: " + it } myFile.eachLine( printFileLine )
这将会输入文件中的每一行,以"File line"为前缀.第一二行代码简单的定义指定文件所在位置的变量.变量名称不具有什么特殊意义,并且与你可以看到的一样, 我们在使用它们的时候将它们结合到一起.因为在Groovy中反斜杠字符有特殊的意义,你需要使用两个来告诉它你真正想要的是反斜杠.
以"myFile = "开始的下一行,创建了一个新的文件对象.一个对象是有关联的方法和数据的集合.例如,一个文件对象可以有它自己位置的描述数据,在这个例子中的"C:\temp\myfile.txt",并且可能有一个方法,在文件存在的时候删除它.在这个例子中我们只使用了"eachLine"方法,我们在代码的最后一行调用的.之前的一行是一个简单闭包的定义,你应该已经见过几次了.
4.字符串处理
Groovy中的字符串,与Java中的字符串具有相同的功能.也就是说,一个Groovy的字符串,仅仅是一个Java字符串同一些额外添加的东西.因为这些,我们可以通过查阅String类的Java文档来找出一些我们可以用它做的有趣的事情.例如,查看对"split"方法的方法摘要的描述部分.这个方法的可以做的事非常有用,可以基于一个正则表达式来拆分一个字符串.我们将在稍后讲述关于正则表达式的更多内容,但是现在你仅需要知道一件事,就是简单的正则表达式就是一个单独的字符.我们想将拆分日期"2005-07-04"的部分,所以我们可以添加一年,得到明年的7月4号(美国独立纪念日).我们可以"
stringDate = "2005-07-04" dateArray = stringDate.split("-") year = dateArray[0].toInteger() year = year + 1 newDate = year + "-" + dateArray[1] + "-" + dateArray[2]
这段代码汇集了我们之前说过的一些事情.这里有两件新的事情,第一是在一个字符串上使用split方法.第二个是在字符串上调用toInteger().调用toInteger()简单的告诉Groovy你想将一个字符串像数字一样看街.看看如果你不使用toInteger()运行第三行运行的代码会发生什么.
另一件事情是你可能注意到toInteger不在String的Java文档中.那是因为它是在Groovy的String上的一个扩展的特征.你同样可以查看Groovy扩展Java对像的文档.