接下來(lái)我們了解下Gradle所使用的Groovy語(yǔ)言
1.字符串
我們?cè)贕radle中經(jīng)崇郧看到代碼的結(jié)尾都沒(méi)有分號(hào)尘分,這是因?yàn)樵贕roovy中踏堡,結(jié)尾分號(hào)不是必須的,這是Groovy語(yǔ)法的特性误证。
單引號(hào)和雙引號(hào)都可以定義一個(gè)字符串常量(Java中單引號(hào)代表定義一個(gè)字符)继薛,但是雙引號(hào)可以做表達(dá)式運(yùn)算
exp
task printStringVar << {
def name = "張三"
print('單引號(hào)的變量計(jì)算:${name}')//String類型
print("雙引號(hào)的變量計(jì)算:${name}")//GString類型,通過(guò)自動(dòng)調(diào)用toString()返回
}
運(yùn)行./gradlew printStringVar 輸出結(jié)果
單引號(hào)的變量計(jì)算:${name}
雙引號(hào)的變量計(jì)算:張三
通過(guò)這種嵌套規(guī)則愈捅,免去了Java中繁瑣的+號(hào)了 遏考,只有一個(gè)變量可以免去花括號(hào)比如$name
Groovy整型和Java類似,如果使用def聲明類型蓝谨,那么整型是可變的灌具,它會(huì)通過(guò)數(shù)值的大小來(lái)匹配類型。并且數(shù)值可以用_下劃線對(duì)數(shù)字分組
- byte
- char
- short
- int
- long
*Java.lang.BigInteger
浮點(diǎn)型 float double java.lang.BigDecimal
Groovy沒(méi)有明確的字符類型像棘,通過(guò)以下三種方式可以創(chuàng)建
char c = 'A' //聲明類型為char
def c2 = 'B' as char //通過(guò)as將類型強(qiáng)制指定為char
def c3 = (char)'C' //通過(guò)類型轉(zhuǎn)換
2.集合
Groovy完全兼容Java集合稽亏,并進(jìn)行了拓展,使得聲明缕题,迭代截歉,查找集合等操作變得非常easy。常見的集合有List烟零、Set瘪松、Map、Queue
- 2.1 List
Java定義List需要實(shí)現(xiàn)一個(gè)List接口的類锨阿,而Groovy就非常簡(jiǎn)單,
task printList << {
def numList = [1,2,3,4,5]
println numList.getClass().name
println numList[1] // 和Java一樣 訪問(wèn)第二個(gè)元素
println numList[-1] // 訪問(wèn)最后一個(gè)元素
println numList[-2] // 訪問(wèn)倒數(shù)第二個(gè)元素
println numList[1..3] // 訪問(wèn)第二到第四個(gè)元素
//可以使用<<向list末尾追加元素宵睦。
numList << 6
numList.each {
print it // 迭代輸出
}
assert [1,7,8].grep(numList ) ==[1] // 取交集
}
for (i in numList[3 ..5]) { //迭代集合的第4-6個(gè)
print i
}
輸出結(jié)果
Task :printList
java.util.ArrayList
2
5
4
[2, 3, 4]
123456
456
Groovy中,負(fù)下標(biāo)表示從右開始墅诡,-1表示倒數(shù)第一個(gè)壳嚎,以此類推 。中間通過(guò)兩個(gè)..可以表示范圍下標(biāo)索引末早。
通過(guò)each表示迭代烟馅,通過(guò)一個(gè)閉包作為參數(shù) it 表示正在迭代的元素,后面會(huì)詳細(xì)講解閉包的it用法
List中元素可以是不同類型,Groovy定義數(shù)組的方式和定義list的方式一樣然磷,只不過(guò)聲明時(shí)需要制定類型郑趁,或者通過(guò)as來(lái)強(qiáng)制制定類型為Array。Groovy不支持Java數(shù)組的初始化方式姿搜。
String[] arrStr = ['Ananas', 'Banana', 'Kiwi']
assert arrStr instanceof String[]
assert !(arrStr instanceof List)
def numArr = [1, 2, 3] as int[]
assert numArr instanceof int[]
assert numArr.size() == 3
//多維數(shù)組
def matrix3 = new Integer[3][3]
assert matrix3.size() == 3
Integer[][] matrix2
matrix2 = [[1, 2], [3, 4]]
assert matrix2 instanceof Integer[][]
List 實(shí)現(xiàn)快速排序
def quickSort(list){
if(list.size() <2)
return list
def pivot = list[list.size().intdiv(2)]
def left = list.findAll{item->item<pivot}
def middle = list.findAll {item->item==pivot}
def right = list.findAll{item->item>pivot}
return (quickSort(left)+middle+quickSort(right))
}
assert quickSort([]) == []
assert quickSort([1]) == [1]
assert quickSort([1,2]) == [1,2]
assert quickSort([2,1,3]) == [1,2,3]
assert quickSort([1.0f,'a',10,null]) == [null,1.0f,10,'a']
assert quickSort('Karin and Dierk') == ' DKaadeiiknnrr'.toList()
- Map
Map跟Java一樣 都是接受一個(gè) K:V鍵值對(duì) ,Groovy穿件的map默認(rèn)類型為java.util.LinkedHashMap
- Map
task printlnMapBase << {
def map = [ 'w': 1280, 'h':1920 ]
println map['w']
println map.w
map.each {
println "Key:${it.key},Value ${it.value}"
}
def key = 'name'
def person = [key: 'Guillaume'] // key實(shí)際上為"key"
assert !person.containsKey('name')
assert person.containsKey('key')
person = [(key): 'Guillaume'] // key實(shí)際上為"name"
assert person.containsKey('name')
assert !person.containsKey('key')
}
Map中通過(guò)[key]或.key的方式來(lái)獲取key對(duì)應(yīng)的value寡润。如果key不存在,則返回null.
當(dāng)我們使用數(shù)字作為key時(shí)舅柜,這個(gè)數(shù)字可以明確的認(rèn)為是數(shù)字梭纹,并不是Groovy根據(jù)數(shù)字創(chuàng)建了一個(gè)字符串。但是如果以一個(gè)變量作為key的話业踢,需要將變量用()包裹起來(lái)栗柒,否則key為變量,而不是變量所代表的值。
引用標(biāo)識(shí)符是.(dot)后的表達(dá)式瞬沦。比如說(shuō)name是person.name的一部分太伊,那么我們可以通過(guò)person."name"或者person.'name'來(lái)引用它。這點(diǎn)與Java不同逛钻,Java不允許這種格式的引用僚焦。eg:
def map = [:]
map."an identifier with a space and double quotes" = "ALLOWED"
map.'with-dash-signs-and-single-quotes' = "ALLOWED"
assert map."an identifier with a space and double quotes" == "ALLOWED"
assert map.'with-dash-signs-and-single-quotes' == "ALLOWED"
- 3.方法
Groovy 中方法括號(hào)是可以省略的(我們一般都省略),甚至返回值return都不用寫
assert 3 == method1(1,2)
def value = method1 1,2
assert value == 3
def method1(int a, int b) {
println a+b
a+b
}
- 閉包(closure)
在Android 的build.gradle 大量使用閉包c(diǎn)losure
之前說(shuō)的一個(gè)參數(shù)可以省略 ,通過(guò)it 返回迭代
如果是map的話曙痘,返回key 和value 一共兩個(gè)參數(shù) 芳悲,那么就不能使用it,需要顯示聲明出來(lái)边坤。
eachMap({ k,v ->
println "${k} is ${v}"
})
def eachMap(closure) {
def map = ["name":"zhangsan","age":"18"]
map.each {
closure(it.key,it.value)
}
}
輸出:
name is zhangsan
age is 18
Groovy的閉包有thisObject名扛、owner、delegate 三個(gè)屬性
thisObject 默認(rèn)就是上線文對(duì)象來(lái)處理閉包中調(diào)用的方法
委托(delegate)
closure的上下文是可以改變的茧痒,通過(guò)Closure#setDelegate()肮韧。這個(gè)特性非常有用:
def myClosure = {println myVar} //I'm referencing myVar from MyClass class
MyClass m = new MyClass()
myClosure.setDelegate(m)
myClosure()
class MyClass {
def myVar = 'Hello from MyClass!'
}
output: Hello from MyClass!
在 《Android Gradle權(quán)威指南》 看到的委托實(shí)例
def person(Closure<Person> closure) { //Closure是groovy.lang下的一個(gè)抽象類 ,泛型為Person
Person p = new Person()
closure.delegate = p
closure.setResolveStrategy(Closure.DELEGATE_FIRST)
closure(p)
}
class Person {
String name
String age
def dumpPerson() {
println "name is ${name},age is ${age}"
}
}
task hello {
person {
name = "momo"
age = "18"
dumpPerson()
}
}