个人博客:
http://www.milovetingting.cn
Groovy基础
Groovy是基于JVM虚拟机的一种动态语言。每个Gradle的build脚本文件都是一个Groovy脚本文件。
字符串
在Groovy中,分号不是必需的。在Groovy中,单引号和双引号都可以定义一个字符串变量 ,单引号标记的是纯粹的字符串变量,而不是对字符串里的表达式做运行,但是双引号可以。
1 2 3 4 5 6 7
| task printString { def str1 = '单引号' def str2 = "双引号" println "单引号定义的字符串类型:"+str1.getClass().name println "双引号定义的字符串类型:"+str2.getClass().name }
|
输出结果:
1 2
| 单引号定义的字符串类型:java.lang.String 双引号定义的字符串类型:java.lang.String
|
而双引号可以做运算:
1 2 3 4 5 6
| task printStringVar{ def name = '张三'
println '单引号的变量计算:${name}' println "双引号的变量计算:${name}" }
|
输出结果:
1 2
| 单引号的变量计算:${name} 双引号的变量计算:张三
|
一个$符号紧跟着一对花括号,花括号里放表达式,如${name}、${1+1}等,只有一个变量的时候,可以省略花括号,如$name。
集合
List
1 2 3 4 5 6 7 8 9 10 11 12 13
| task printList { def numList = [1,2,3,4,5] println numList.getClass().name
println numList[1] println numList[-1] println numList[-2] println numList[1..3]
numList.each { println it } }
|
Groovy还为List提供了非常方便的迭代操作,这就是each方法。
Map
Map用法和List想像,只不过它的值是一个K:V键值对。访问也非常灵活,采用map[key]或者map.key都可以。
1 2 3 4 5 6 7 8 9 10 11
| task printMap{ def map1 = ['name':'张三','age':18] println map1.getClass().name
println map1['name'] println map1.age
map1.each{ println "key:${it.key},Value:${it.value}" } }
|
方法
括号可以省略
1 2 3 4 5 6 7 8
| task invokeMethod{ method1(1,2) method1 1,2 }
def method1(int a,int b){ println a+b }
|
return可以不写
在Groovy中,定义有返回值的方法时,return语句不是必需的。当没有return时,Groovy会把方法执行过程中的最后一句代码作为返回值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| task printMethodReturn{ def max1 = method2 1,2 def max2 = method2 3,5 println "max1:${max1},max2:${max2}"
}
def method2(int a,int b){ if(a>b){ a }else{ b } }
|
代码块可以作为参数传递
JavaBean
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| task helloJavaBean{ Person p = new Person() println "名字是:${p.name}" p.name="张三" println "名字是:${p.name}" println "年龄是:${p.age}" }
class Person{ private String name
public int getAge(){ 18 } }
|
在Groovy中,并不是一定要定义成员变量才能作为类的属性访问。我们直接用getter/setter方法,也一样可以当作属性访问。
闭包
闭包是Groovy的一个非常重要的特性,是DSL的基础。
初识闭包
1 2 3 4 5 6 7 8 9 10 11 12 13
| task helloClosure{ customEach{ println it }
eachMap{k,v->println "${k} is ${v}"} }
def customEach(closure){ for(int i in 1..10){ closure(i) } }
|
向闭包传递参数
当闭包有一个参数时,默认就是it,当有多个参数时,it就不能表达了,我们需要把参数一一列出。
1 2 3 4 5 6
| def eachMap(closure){ def map1 = ["name":"张三","age":18] map1.each{ closure(it.key,it.value) } }
|
闭包委托
Groovy的闭包有thisObject,owener,delegate三个属性。默认情况下,delegate和owner是相等的,但是delegate是可以被修改的。
thisObject的优先级最高,thisObject其实就是这个构建脚本的上下文,它和脚本中的this对象是相等的。优先级从高到低依次是:thisObject>owner>delegate。
在DSL中,比如Gradle,我们一般会指定delegate为当前的it,这样我们在闭包内就可以对该it进行配置,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| task configClosure{ person{ name="张三" age = 18 dumpPerson() } }
class Person{ String name int age
def dumpPerson(){ println "name:${name},age:${age}" } }
def person(Closure<Person> closure){ Person p = new Person() closure.delegate = p closure.setResolveStrategy(Closure.DELEGATE_FIRST) closure(p) }
|
DSL
DSL,即Domain Specific Language,领域特定语言,就是专门关注某一领域的语言,在于专,而不是全。
Gradle就是一门DSL,它是基于Groovy,专门解决自动化构建的DSL。