Groovy是基于JVM虚拟机的一种动态语言,支持闭包,支持DSL
字符串
在Groovy中,单引号和双引号都可以定义一个字符串常量,但是单引号不能对字符串里的表达式做运算,单引号没有运算能力
集合
List定义及访问:
task pringList << {
def numList =[1, 2, 3, 4, 5, 6];
println numList.getClass().name
pringln numList[1] // 访问第二个元素
pringln numList[-1] // 访问最后一个元素
pringln numList[1..3] // 访问第二个到第四个元素
numList.each { // 迭代操作,each方法,该方法接受一个闭包作为参数,可以访问List中的每个元素
pringln it
}
}
Map定义与访问:
task printlnMap << {
def map1 =['width' : 1024, 'height' : 768]
println map1.getClass().name
println map1['width']
pringln map1.height
map1.each { // 被迭代的元素是一个Map.Entry
println "Key:${it.key}, Value:${it.value}"
}
对于集合,还提供了诸如collect、find、findAll等便捷方法
方法
Groovy可以省略(),变成invokeMethod parm1、 parm2
task invokeMethod << {
method1(1, 2)
method 1, 2
}
def method(int a, int b) {
println a+b
}
Groovy中带返回值的方法,return语句不是必须的,当没有return时,会将方法执行过程中最后一句代码作为其返回值
代码块---被花括号包围的代码,及闭包,Groovy允许其作为参数传递,
numList.each({println it}) // 呆板写法
numList.each({ // 格式化一下
println it
})
Groovy规定,如果方法的最后一个参数是闭包,可以放到方法外面
numList.each(){
println it
}
然后去掉括号就变成我们经常看到的样式
JavaBean
task helloJavaBean << {
Person p = new Person()
println "名字是:!${p.name}"
p.name = "张三"
pringln "名字是:!${p.name}"
println "年龄是:!${p.age}" // 并不一定要定义成员变量才能作为类的属性访问,getter/setter方法也一样,但是不能修改age的值
}
class Person {
private String name
public int getAge() {
12
}
}
闭包
使代码灵活、轻量、可复用
实现一个类似each的闭包功能
task helloCosure << {
customEach {
println it
}
eachMap {k, v ->
println "${k} is ${v}"
}
}
def customEach(closure) { // closure用于接收一个闭包(代码块),如果只有一个参数,那就是我们的it变量
for(int i in 1..10) {
closure(i)
}
}
def eachMap(closure) {
def map1 = ["name":"张三", "age":18]
map1.each {
colsure(it.key, it.value)
}
}
Groovy闭包的强大之处在于它支持闭包方法的委托,其闭包邮thisObject、owner、delegate三个属性
thisObject其实就是构建这个脚本的上下文,它和脚本中的this对象是相等的。
delegate与owner默认情况下是相等的,但是delegate是可以被修改的
闭包内方法的处理顺序是thisObject>owner>delegate
在DSL中,比如Gradle,我们一般会指定delegate为当前的it,这样就可以对该it进行配置,或调用其方法:
task configClosure << {
person {
personName = "张三"
personAge = 20
dumpPerson()
}
}
class Person {
String personName
int personAge
def dumpPerson() {
println "name is ${personName}, age is ${personAge}"
}
}
def person(closure<Person> closure) {
Person p = new Person()
closure.delegate = p
// 委托模式优先
closure.setResolveStrategy(Closure.DELEGATE_FIRST);
closure(p)
}
在使用person方法创建一个Person实例时,可以在闭包里直接对该Person实例配置。