Gradle系列之Groovy基礎篇

原文首發於微信公衆號:躬行之(jzman-blog),歡迎關注交流!

上一篇學習了 Gradle 的入門知識,Gradle 基於 Groovy,今天學習一下 Groovy 的基礎知識,Groovy 是基於 JVM 虛擬機的一種動態語言,語法與 Java 語法相似,Groovy 徹底兼容 Java,每一個 Gradle 文件都是一個 Groovy 腳本文件,Gradle 文件基於 Groovy 語法,而 Groovy 又兼容 Java,故能夠在 Gradle 文件中寫 Java 代碼,在此基礎上增長了不少新特性,如支持閉包、DSL等,能夠說 Groovy 是一門很是靈活的動態腳本語言,閱讀本文以前能夠先閱讀下面這篇文章:java

下面針對 Gradle 來學習一下 Groovy 的一些基礎知識。數組

  1. 字符串
  2. 集合
  3. 方法
  4. JavaBean
  5. 關於閉包

字符串

說一個 Groovy 的特性,在 Groovy 中分號不是必須的,其單引號是雙引號都定義的是一個字符串常量,不一樣之處是單引號是純粹的字符串常量,不會對該字符串裏面的表達式作運算,而使用雙引號定義的字符串常量可使用合法表達式作相關運算,測試代碼以下:微信

task stringTest{
    //使用def關鍵字定義變量,
    def str1 = "雙引號"
    def str2 = '單引號'
    
    println "雙引號定義的字符串:"+str1
    println "雙引號定義的字符串:"+str1.class
    println "單引號定義的字符串:"+str2
    
    //變量動態變化
    str1 = true;
    println "雙引號定義的字符串:"+str1.class
    
    //使用$運算符
    println "雙引號定義的字符串:${str1}"
    //只有一個變量的時候能夠省去中括號
    println "雙引號定義的字符串:$str1"
    
    //單引號定義的字符串不能使用表達式進行運算
    println '單引號定義的字符串:$str2'
}

下面是執行結果,參考以下:閉包

PS E:\Gradle\study\Groovy> gradle stringTest

> Configure project :
雙引號定義的字符串:雙引號
雙引號定義的字符串:class java.lang.String
單引號定義的字符串:單引號
雙引號定義的字符串:class java.lang.Boolean
雙引號定義的字符串:true
雙引號定義的字符串:true
單引號定義的字符串:$str2


BUILD SUCCESSFUL in 1s

集合

Groovy 中也有集合的概念,主要看一下經常使用的 List、Map,下面將對 List 和 Map 經常使用操做進行介紹。工具

那麼如何在 Groovy 中定義 List 呢,Groovy 中的 List 的定義方式相似於 Java 中的數組,具體操做參考下面代碼:post

task list{
    //定義List
    def list = [1,2,3,4,5,6];
    def weekList = ['星期一','星期二','星期三','星期四','星期五','星期六','星期日'];
    println "list的類型:"+list.class
    println "weekList的類型:"+weekList.class
    
    //訪問集合裏面的元素
    println '第一個元素:'+list[0]//訪問第一個元素
    println '第二個元素:'+list[1]//訪問第二個元素,以此類推
    
    println '最後一個元素:'+list[-1]//訪問最後一個元素
    println '倒數第二個元素:'+list[-2]//訪問倒數第二個元素,以此類推
    println '某個範圍內元素:'+list[2..4]//訪問某個範圍內元素,以此類推
    
    //使用each遍歷集合中的元素
    weekList.each{
        //使用it做爲迭代的元素變量,不能寫錯喔
        println it
    }
}

下面是上述代碼的執行結果,參考以下:學習

PS E:\Gradle\study\Groovy\ListMap> gradle list

> Configure project :
list的類型:class java.util.ArrayList
weekList的類型:class java.util.ArrayList
第一個元素:1
第二個元素:2
最後一個元素:6
倒數第二個元素:5
某個範圍內元素:[3, 4, 5]
星期一
星期二
星期三
星期四
星期五
星期六
星期日


BUILD SUCCESSFUL in 2s

那麼如何在 Groovy 中定義 Map 呢,Groovy 中的 Map 固然也是鍵值對,具體定義及操做參考下面代碼:測試

task map{
    
    //定義Map
    def map = ['name':'Groovy', 'age':10];
    println "map的類型:"+map.getClass().name;
    
    //訪問Map裏面的元素
    println map.name;
    println map['name'];
    
    //遍歷Map中的元素
    map.each{
        println "Key:${it.key},value:${it.value}"
    }
}

下面是上述代碼的執行結果,參考以下:gradle

PS E:\Gradle\study\Groovy\ListMap> gradle map

> Configure project :
map的類型:java.util.LinkedHashMap
Groovy
Groovy
Key:name,value:Groovy
Key:age,value:10


BUILD SUCCESSFUL in 2s

關於 Groovy 的集合就瞭解這麼多。ui

方法

Groovy 中的方法和 Java 中的方法相似,只是寫法上更加靈活,Groovy 中 return 不是必須的,在不寫 return 的時候,Groovy 會將最後一句代碼做爲該方法的返回值。代碼塊指的是一段被花括號包圍的代碼,Groovy 中可將代碼塊做爲一個參數進行傳遞,能夠參考前面關於集合的遍歷部分,參考代碼以下:

task method{
    //方法調用
    methodA(1, 2)
    methodA 1, 2 
    
    //獲取方法返回的結果
    def a = methodA 10, 20
    println '獲取方法返回的結果:'+a
    
    //代碼塊做爲參數傳遞
    def list = [1,2,3,4,5];
    list.each(
        //閉包參數
        {
        //    println it
        }
    )
    
    //Groovy規定,若是方法的最後一個參數是閉包,能夠直接放到方法外面
    list.each(){
    //    println it
    }
    
    //簡寫方式
    list.each{
        println it
    }
}

//方法的定義
def methodA(int a, int b){
    println a + b
    //Groovy中return語句不是必須的,默認將最後一句代碼的結果做爲返回值
    a + b
}

下面是上述代碼參考以下:

PS E:\Gradle\study\Groovy\Method> gradle method

> Configure project :
3
3
30
獲取方法返回的結果:30
1
2
3
4
5


BUILD SUCCESSFUL in 2s

JavaBean

Groovy 中的 JavaBean 相較 Java 中的比較靈活,能夠直接使用 javaBean.屬性的方式獲取和修改 JavaBean 的屬性值,無需使用相應的 Getter、Setter 方法,直接看代碼:

task javaBean{
    //Groovy中定義JavaBean
    Student student = new Student()
    student.name = "Groovy"
    student.age = 10
    
    student.setName("Gradle")
    println "名字是:"+student.name
    //不能調用Getter方法獲取值
//    println "名字是:"+student.getName
    println "年齡是:${student.age}"
    println "分數是:"+student.score
}

class Student{
    private String name
    private int age
    //定義的Getter方法所對應的屬性能夠直接調用
    public String getScore(){
        100
    }
    
    //屬性的Getter、Setter方法
    public String setName(String name){
        this.name = name
    }
    
    public void getName(){
        name
    }
}

下面是上述代碼的執行結果:

PS E:\Gradle\study\Groovy\JavaBean> gradle javaBean

> Configure project :
名字是:Gradle
年齡是:10
分數是:100


BUILD SUCCESSFUL in 2s

閉包

閉包是大多數腳本語言具備的一個特性,如 JavaScript、Groovy 等,閉包就是一個使用花括號包圍的代碼塊,下面來學習 Groovy 中的閉包,主要有兩部分:閉包及閉包參數傳遞和閉包委託。

閉包及其參數傳遞

下面來看一下如何定義一個閉包以及相關參數的傳遞,直接上代碼:

task closure{
    //自定義閉包的執行
    mEach{
        println it
    }
    
    //向閉包傳遞參數
    mEachWithParams{m,n -> //m,n ->將閉包的參數和主體區分離開來
        println "${m} is ${n}"
    }
}

//1.定義一個方法,參數closure用於接收閉包
//2.閉包的執行就是花括號裏面代碼的執行
//3.閉包接收的參數就是閉包參數closure參數中的i,若是是一個參數默認就是it變量
def mEach(closure){
    for(int i in 1..5){
        closure(i)
    }
}

//向閉包傳遞參數
def mEachWithParams(closure){
    def map = ["name":"Groovy","age":10]
    map.each{
        closure(it.key, it.value)
    }
}

上面代碼中定義了閉包以及如何進行閉包的參數的傳遞,當閉包只有一個參數時,默認就是 it,反之閉包有多個參數時,就須要將參數定義出來,具體可參考上述代碼,下面是執行結果:

PS E:\Gradle\study\Groovy\Closure> gradle delegate

> Configure project :
1
2
3
4
5
name is Groovy
age is 10

BUILD SUCCESSFUL in 2s
閉包委託

Groovy 閉包的強大之處在於它支持閉包方法的委託,Groovy 的閉包有三個屬性:thisObject、owner、delegate,當在一個閉包中調用定義的方法時,由這三個屬性來肯定該方法由哪一個對象來執行,默認 owner 和 delegate 是相等的,其中 delete 是能夠被修改的,Gradle 中閉包的不少功能都是經過修改 delegate 來實現的。下面經過定義一個閉包以及方法,經過打印來講明這三個屬性的一些區別:

//閉包的委託
task delegate{
    new Delegate().test{
        //Groovy閉包的三個屬性:thisObject、owner、delegate
        println "thisObject:${thisObject.getClass()}"
        println "owner:${owner.getClass()}"
        println "delegate:${delegate.getClass()}"
        
        //閉包默認it
        println "閉包默認it:"+it.getClass()
        
        //定義的方法,優先使用thisObject來處理
        method()
        //閉包中的方法
        it.method()
    }
}

def method(){
    println "mththod in root:${this.getClass()}"
}

class Delegate{
    def method(){
        println "mththod in Delegate:${this.getClass()}"
    }
    
    //閉包
    def test(Closure<Delegate> closure){
        closure(this);
    }
}

下面是上述代碼的執行結果,參考以下:

PS E:\Gradle\study\Groovy\Closure> gradle delegate

> Configure project :

thisObject:class build_3ajca04o1rprxygcsq0ajvt7i
owner:class build_3ajca04o1rprxygcsq0ajvt7i$_run_closure2
delegate:class build_3ajca04o1rprxygcsq0ajvt7i$_run_closure2
閉包默認it:class Delegate
mththod in root:class build_3ajca04o1rprxygcsq0ajvt7i
mththod in Delegate:class Delegate


BUILD SUCCESSFUL in 2s

當在閉包中調用方法 method() 時,發現是 thisObject 調用了 method() 方法,而不是 owner 或 delegate,說明閉包中優先使用 thisObject 來處理方法的執行,同時能夠看到 owner 和 delegate 是一致的,可是 owner 比 delegate 的優先級要高,因此閉包中方法的處理順序是:thisObject > owner > delegate。

Gradle 中通常會指定 delegate 爲當前的 it,這樣咱們將能夠經過 delegate 指定的對象來操做 it 了,下面指定閉包的 delegate 並設置委託優先,讓委託的具體對象來執行其方法,下面是測試代碼:

task student{
    configStudent{
        println "當前it:${it}"
        
        name = "Groovy"
        age = 10
        getInfo()
    }
}

class Student{
    String name
    int age
    def getInfo(){
        println "name is ${name}, age is ${age}"
    }
}

def configStudent(Closure<Student> closure){
    Student student = new Student()
    //設置委託對象爲當前建立的Student實例
    closure.delegate = student
    //設置委託模式優先,若是不設置閉包內方法的處理者是thisObject
    closure.setResolveStrategy(Closure.DELEGATE_FIRST)
    //設置it變量
    closure(student)
}

下面是上述代碼的執行結果,參考以下:

PS E:\Gradle\study\Groovy\Closure> gradle student

> Configure project :

當前it:Student@18f6d755
name is Groovy, age is 10


BUILD SUCCESSFUL in 2s

總結

學習 Groovy 的目的仍是爲了加深對 Gradle 構建工具的理解,上面經過五個方面對 Groovy 有了初步的人認識,後續若是有須要在看 Groovy 的高級用法。能夠關注公衆號:躬行之(jzman-blog),一塊兒交流學習。

1.png

相關文章
相關標籤/搜索