Groovy学习之——闭包

一、简介:

Groovy是动态弱类型语言,即Groovy不要求声明变量的类型、方法的参数或者方法的返回值。这意味着在不同环境下,变量可以以多种方式使用。

闭包是一个类型为groovy.lang.Closure的代码块,与其他语言的lambdas特性类似。闭包可以赋值给变量,作为参数传递给方法,并且像普通方法一样来调用。

1.闭包格式

闭包[closureParameters->] 是可选的,参数的类型也是可选的。如果我们不指定参数的类型,会由编译器自动推断。如果闭包只有一个参数,这个参数可以省略,我们可以直接使用it来访问该参数

{
          [closureParameters -> ] 
          statements 
      }
举个栗子
{ item++ } 
{ -> item++ } 
{ println it } 
{ it -> println it } 
{ name -> println name } 
{ String x, int y -> println "hey ${x} the value is ${y}" } 
{ reader -> def line = reader.readLine() line.trim() }


二、闭包参数

1.隐式闭包参数

每个没有显示定义任何参数的闭包到可以访问一个隐式参数it。it代表这个闭包第一个传递进来的参数。见代码:

class ProjectVersion{
  Integer major //主要版本
  Integer minor //次要版本
}

def incrementMajorVersion = {
  it.major++
}

ProjectVersion version = new ProjectVersion(major : 1, minor : 10)
incrementMajorVersion(version)
assert version.major == 2
println version.major

闭包的参数声明写在‘->’符号前,调用闭包的的标准写法是:闭包名.call(闭包参数)。见代码:

def toTriple = {n -> n * 3}  
assert toTriple.call( 5 ) == 15 

对于单一存在的参数it可以不用声明,直接使用it,it在Groovy中有着特殊的意义。见代码:

c = { it*3 }  
assert c( ‘run’ ) == ‘runrunrun’

当且仅当闭包中仅有一个参数,且不显示声明,it具有唯一参数引用的作用,反之,如果在闭包参数声明中有参数,那么闭包的逻辑代码块中的it降级为普通的变量。见代码:

    c = { def it = 789 }
              //arror it已经被隐式定义
    c = { value1 -> def it = 789; [value1, it] }  
              //OK  it降级为一个参数 

    assert c( 456 ) == [456, 789]  
    c = {-> def it = 789; it }  
    assert c() == 789           
             //OK 隐式参数有且只有一个,由it代替

2.显示的闭包参数

class ProjectVersion{
  Integer major //主要版本
  Integer minor //次要版本
}

def incrementMajorVersion = { ProjectVersion version -> //显示参数
  version.major++
}

ProjectVersion version = new ProjectVersion(major : 1, minor : 10)
incrementMajorVersion.call(version)  //标准调用方法
assert version.major == 2
println version.major


三、闭包返回值

闭包总会返回一个值,返回值是闭包的最后一条语句的值(如果没有显式的return语句)。如果c是无参数闭包,那么它的标准调用方法是c.call(),它的简洁调用方法是c()

def a = 'coffee'  
def c = {  
  def b = 'tea'  
  a + ' and ' + b //a refers to the variable a outside the closure,  
                  //and is remembered by the closure  
}  
assert c() == 'coffee and tea' //short for c.call() 


我们可以将闭包赋给变量,然后可以将变量作为函数来调用

或者调用闭包的call方法也可以调用闭包,闭包实际上是groovy.lang.Closure类型。

泛型版本的泛型表示闭包的返回类型。

def fun = { println("$it") } 
fun(1234) 
//闭包赋给变量,然后可以将变量作为函数来调用 

Closure date = { println(LocalDate.now()) } 
date.call() 
//调用闭包的call()方法

Closure<LocalTime> time = { LocalTime.now() } 
println("now is ${time()}")
//范型返回值 

四、其他一些用法

1.闭包作为方法参数

class ProjectVersion{
  Integer major //主要版本
  Integer minor //次要版本
}

Integer incrementVersion(Closure closure, Integer count){//闭包作为第一个参数
  closure() + count
}

ProjectVersion version = new ProjectVersion(major : 1, minor : 10)
assert incrementVersion({ version.minor }, 2) == 12

2.闭包委托

此方法在Gradle构建脚本中大量用到。闭包代码在委托的闭包上执行,默认的,这个委托就是闭包所有者,闭包的隐式变量delegate允许你重新定义默认的所有者。如下代码设置了委托给ProjectVersion实例,这意味着所有闭包都在这个实例上执行。

class ProjectVersion{
  Integer major
  Integer minor
  
  void increment(Closure closure){ //用闭包作为参数
    closure.resolveStrategy = Closure.DELEGATE_ONLY //只处理委托引用
    closure.delegate = this  //设置闭包委托
    closure()
  }
}

ProjectVersion project = new ProjectVersion(major: 1, minor: 10)
project.increment { major += 1}
assert project.major == 2

五、在Gradle构建脚本中使用Groovy

在大多数情况下,在构建脚本中调用的属性和方法都自动委托给org.gradle.api.Project实例

apply plugin: 'java'
//调用Project的apply方法,关于参数,提供一个只有一个键值对的Map,方法调用省略括号

version = '0.1'
//通过调用Project的setter方法为项目设置版本属性

repositorier{
  mavenCentral()
  //调用闭包委托的mavenCentral()方法
}
//调用Project的repositories方法并传递一个闭包

dependencies {
  compile 'commons-codec:1.6'
  //调用闭包委托的对象的compile方法,用一个String作为参数,方法调用省略了括号
}
//调用Project的dependencies方法,并传递一个闭包参数

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值