Gradle閱讀筆記-第二章groovy基礎
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例項配置。