(2.2.9.3)groovy的闭包
闭包的样子闭包,英文叫 Closure,是 Groovy 中非常重要的一个数据类型或者说一种概念了。闭包的历史来源,种种好处我就不说了。我们直接看怎么使用它! 闭包,是一种数据类型,它代表了一段可执行的代码。其外形如下: def aClosure = {//闭包是一段代码,所以需要用花括号括起来.. String param1,int param2 -> //这个箭头很关键。箭头前面是参数定义,箭头后面是代码 println "this is code" //这是代码,最后一句是返回值, //也可以使用 return,和 Groovy 中普通函数一样 } 简而言之,Closure 的定义格式是: def xxx = {paramters -> code} //或者 def xxx = {无参数,纯 code} 这种 case 不需要->符号 说实话,从 C/C++ 语言的角度看,闭包和函数指针很像。闭包定义好后,要调用它的方法就是: 闭包对象.call(参数) 或者更像函数指针调用的方法: 闭包对象(参数) aClosure.call("this is string",100) 或者 aClosure("this is string",100) 上面就是一个闭包的定义和使用。在闭包中,还需要注意一点: 如果闭包没定义参数的话,则隐含有一个参数,这个参数名字叫 it,和 this 的作用类似。it 代表闭包的参数。 比如: def greeting = { "Hello,$it!" } assert greeting('Patrick') == 'Hello,Patrick!' 等同于: def greeting = { it -> "Hello,sans-serif"> 但是,如果在闭包定义时,采用下面这种写法,则表示闭包没有参数!def noParamClosure = { -> true }
def testClosure(int a1,String b1,Closure closure){ //do something closure() //调用闭包 } 那么调用的时候,就可以免括号! testClosure (4,"test",{ println "i am in closure" } ) //红色的括号可以不写.. 注意,这个特点非常关键,因为以后在 Gradle 中经常会出现图 7 这样的代码:
经常碰见图 7 这样的没有圆括号的代码。省略圆括号虽然使得代码简洁,看起来更像脚本语言,但是它这经常会让我 confuse(不知道其他人是否有同感),以 doLast 为例,完整的代码应该按下面这种写法: doLast({ println 'Hello world!' }) 有了圆括号,你会知道 doLast 只是把一个 Closure 对象传了进去。很明显,它不代表这段脚本解析到 doLast 的时候就会调用 println 'Hello world!' 。 但是把圆括号去掉后,就感觉好像 println 'Hello world!'立即就会被调用一样! 2.如何确定 Closure 的参数 另外一个比较让人头疼的地方是,Closure 的参数该怎么搞?还是刚才的 each 函数: 如何使用它呢?比如:看起来很轻松,其实:
我们能写成下面这样吗? iamList.each{String name,int x -> return x } //运行的时候肯定报错! 所以,Closure 虽然很方便,但是它一定会和使用它的上下文有极强的关联。要不,作为类似回调这样的东西,我如何知道调用者传递什么参数给 Closure 呢? 此问题如何破解?只能通过查询 API 文档才能了解上下文语义。比如下图 8:
图 8 中:
对 Map 的 findAll 而言,Closure 可以有两个参数。findAll 会将 Key 和 Value 分别传进去。并且,Closure 返回 true,表示该元素是自己想要的。返回 false 表示该元素不是自己要找的。示意代码如图 9 所示:
Closure 的使用有点坑,很大程度上依赖于你对 API 的熟悉程度,所以最初阶段,SDK 查询是少不了的。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |