接下来我们了解下Gradle所使用的Groovy语言
1.字符串
我们在Gradle中经常看到代码的结尾都没有分号,这是因为在Groovy中,结尾分号不是必须的,这是Groovy语法的特性。
单引号和双引号都可以定义一个字符串常量(Java中单引号代表定义一个字符),但是双引号可以做表达式运算
exp
task printStringVar << {
def name = "张三"
print('单引号的变量计算:${name}')//String类型
print("双引号的变量计算:${name}")//GString类型,通过自动调用toString()返回
}
运行./gradlew printStringVar 输出结果
单引号的变量计算:${name}
双引号的变量计算:张三
通过这种嵌套规则,免去了Java中繁琐的+号了 ,只有一个变量可以免去花括号比如$name
Groovy整型和Java类似,如果使用def声明类型,那么整型是可变的,它会通过数值的大小来匹配类型。并且数值可以用_下划线对数字分组
- byte
- char
- short
- int
- long
*Java.lang.BigInteger
浮点型 float double java.lang.BigDecimal
Groovy没有明确的字符类型,通过以下三种方式可以创建
char c = 'A' //声明类型为char
def c2 = 'B' as char //通过as将类型强制指定为char
def c3 = (char)'C' //通过类型转换
2.集合
Groovy完全兼容Java集合,并进行了拓展,使得声明,迭代,查找集合等操作变得非常easy。常见的集合有List、Set、Map、Queue
- 2.1 List
Java定义List需要实现一个List接口的类,而Groovy就非常简单,
task printList << {
def numList = [1,2,3,4,5]
println numList.getClass().name
println numList[1] // 和Java一样 访问第二个元素
println numList[-1] // 访问最后一个元素
println numList[-2] // 访问倒数第二个元素
println numList[1..3] // 访问第二到第四个元素
//可以使用<<向list末尾追加元素。
numList << 6
numList.each {
print it // 迭代输出
}
assert [1,7,8].grep(numList ) ==[1] // 取交集
}
for (i in numList[3 ..5]) { //迭代集合的第4-6个
print i
}
输出结果
Task :printList
java.util.ArrayList
2
5
4
[2, 3, 4]
123456
456
Groovy中,负下标表示从右开始,-1表示倒数第一个,以此类推 。中间通过两个..可以表示范围下标索引。
通过each表示迭代,通过一个闭包作为参数 it 表示正在迭代的元素,后面会详细讲解闭包的it用法
List中元素可以是不同类型,Groovy定义数组的方式和定义list的方式一样,只不过声明时需要制定类型,或者通过as来强制制定类型为Array。Groovy不支持Java数组的初始化方式。
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
//多维数组
def matrix3 = new Integer[3][3]
assert matrix3.size() == 3
Integer[][] matrix2
matrix2 = [[1, 2], [3, 4]]
assert matrix2 instanceof Integer[][]
List 实现快速排序
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一样 都是接受一个 K:V键值对 ,Groovy穿件的map默认类型为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实际上为"key"
assert !person.containsKey('name')
assert person.containsKey('key')
person = [(key): 'Guillaume'] // key实际上为"name"
assert person.containsKey('name')
assert !person.containsKey('key')
}
Map中通过[key]或.key的方式来获取key对应的value。如果key不存在,则返回null.
当我们使用数字作为key时,这个数字可以明确的认为是数字,并不是Groovy根据数字创建了一个字符串。但是如果以一个变量作为key的话,需要将变量用()包裹起来,否则key为变量,而不是变量所代表的值。
引用标识符是.(dot)后的表达式。比如说name是person.name的一部分,那么我们可以通过person."name"或者person.'name'来引用它。这点与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 中方法括号是可以省略的(我们一般都省略),甚至返回值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 大量使用闭包closure
之前说的一个参数可以省略 ,通过it 返回迭代
如果是map的话,返回key 和value 一共两个参数 ,那么就不能使用it,需要显示声明出来。
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 三个属性
thisObject 默认就是上线文对象来处理闭包中调用的方法
委托(delegate)
closure的上下文是可以改变的,通过Closure#setDelegate()。这个特性非常有用:
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权威指南》 看到的委托实例
def person(Closure<Person> closure) { //Closure是groovy.lang下的一个抽象类 ,泛型为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()
}
}