Gradle學(xué)習(xí)1——Groovy基本介紹

學(xué)習(xí)Gradle,前前后后總結(jié)了一些內(nèi)容,然后整理出了一個(gè)系列,共計(jì)10篇文章,與大家分享:

  1. Groovy基本介紹
  2. 開始使用Gradle
  3. 自定義屬性
  4. 深入了解Task和構(gòu)建生命周期
  5. Gradle增量式構(gòu)建
  6. 掛接到構(gòu)建生命周期
  7. 編寫和使用自定義Task
  8. 依賴管理
  9. 多項(xiàng)目構(gòu)建
  10. 自定義Gradle插件

學(xué)習(xí)本系列前可以下載相關(guān)的github項(xiàng)目gradleLearnDemo
地址:https://github.com/sososeen09/gradleLearnDemo

0 前言

Gradle腳本使用的是Groovy語言,Groovy也是基于JVM的一種動(dòng)態(tài)語言,基于Java并擴(kuò)展了Java語言。Groovy會(huì)使寫Java程序就要寫腳本一樣簡單,寫完就可以執(zhí)行,所以看起來也像是一門腳本語言。Groovy內(nèi)部會(huì)把代碼編譯為Java class文件然后啟動(dòng)虛擬機(jī)來執(zhí)行,這些過程,我們開發(fā)人員是不用管的。

Gradle是一種DSL,也即是 Domain Specific Language 領(lǐng)域特定語言。說白了DSL就是一種行話,這個(gè)語言在Gradle中可以識(shí)別,在其它地方就用不了了。

學(xué)習(xí)Gradle,我們不必要精通Groovy語言,但還是需要了解一些Groovy的基本知識(shí),比如def關(guān)鍵字、返回語句、字符串、集合、閉包等。下面,我們就來簡單介紹一下。

1 Groovy代碼的執(zhí)行

前面我們說了,Groovy很像是一門腳本語言,我們來看一下怎么回事。
創(chuàng)建一個(gè)HelloGroovy.groovy文件,里面就一行代碼

println 'hello groovy!'

然后執(zhí)行命令groovy HelloGroovy.groovy,得到結(jié)果

hello groovy!

是不是很簡單,很像腳本語言。

2 Groovy中的字符串

Groovy 對字符串支持相當(dāng)強(qiáng)大,可以使用多種字符串,包括單引號、雙引號、三引號。

String str='hello groovy!'

String getStr(){
    'hello groovy!'
}

String str1='hello'
String str2=' groovy!'
println 'hello groovy!'
println "hello groovy!"
println "$str"
println getStr()
println "${str1+str2}"
println 'hello $str2'  //單引號,直接打印內(nèi)容

使用單引號會(huì)直接打印字符串的內(nèi)容,不會(huì)對美元$符號的內(nèi)容進(jìn)行轉(zhuǎn)義。使用雙引號的功能更加強(qiáng)大,字符串中使用美元符$后面可以跟字符串變量,如"$str",也可以跟表達(dá)式如 "${str1+str2}",如果跟表達(dá)式,記得要用{}括起來。

三引號用的比較少,可以支持字符串內(nèi)容換行,我們了解一下就行。

println ''' aa
bb

cc
'''

我們在getStr()方法中并沒有使用return語句,這是因?yàn)镚roovy默認(rèn)是把最后一行的執(zhí)行結(jié)果進(jìn)行返回。如果你需要返回的結(jié)果正好是最后一行,就可以省略return。

另外,在Groovy中,語句的最后的“;”號是可以省略的。還有一點(diǎn)就是Groovy中在調(diào)用函數(shù)的時(shí)候可以不加括號,比如,println ("hello")println "hello" 的意思是一樣的

3 def關(guān)鍵字

def關(guān)鍵字很像是Java中的Object,在定義變量或者方法的時(shí)候使用def,如果沒有指定具體的參數(shù)類型。在運(yùn)行階段Groovy會(huì)自動(dòng)判斷參數(shù)類型。

def a = 1, b = 2
def str = "hello"
println a + b
println str

實(shí)際上我們在定義變量的時(shí)候是可以省略def的,如

a = 1
b = 2
str = "hello"

但是,最好還是加上def,這是一種好的實(shí)踐。
你還可以在定義變量的時(shí)候,在def后面再加上具體的參數(shù)類型,如

def int a = 1
def String str = "hello"

使用def定義方法的返回值類型,可以返回任意類型。如果指定了具體的返回值類型,就要正確的返回,否則會(huì)報(bào)錯(cuò)。

4 集合

Groovy的基本類型與Java一樣。對于集合類型的數(shù)據(jù),List的具體實(shí)現(xiàn)是ArrayList。Map集合的具體實(shí)現(xiàn)是LinkedHashMap。

4.1 List

下面我們來簡單了解一下如果使用。List使用一個(gè) []中括號來括起來來表示的。

//定義一個(gè)List
def lists=['groovy','gradle','android']

//打印集合size
println lists.size

//打印集合中的數(shù)據(jù)
lists.each{
    list->println list
}

取出集合中的數(shù)據(jù)直接用索引就可以了。比如:

assert lists[0]=='groovy'

對于集合中變量的存儲(chǔ),我們是不需要擔(dān)心數(shù)組越界的,如果索引超過當(dāng)前長度,List會(huì)自動(dòng)在該索引中添加元素。比如

lists[100]=100
println lists.size
println lists[99]

打印結(jié)果,會(huì)發(fā)現(xiàn)集合的size變?yōu)?01。index為99的集合數(shù)據(jù)為null。

4.2 Map

Map的表示就是用中括號[]括起來的 key:value形式。

def map=["key1":"hello","key2":"groovy","key3":true]
println map.size()

map.forEach{
    key,value->
    println "$key :$value"
}

結(jié)果是:

3
key1 :hello
key2 :groovy
key3 :true

獲取Map的元素

println map.'key1'
println map['key1']

添加元素

map.'key4'='android'
println map['key4']

5 Groovy的類

Groovy中的類與Java中的類的寫法類似,但是要更簡潔一些。
我們在Hello.groovy文件中寫一個(gè)HelloWorld類。

class HelloWorld{
    String msg='hello world'
    
    HelloWorld(){
        
    }

    HelloWorld(String msg){
        this.msg=msg
    }

    void sayHello(){
        println msg
    }
}

def say={
    new HelloWorld('hello').sayHello()
}

def getMsg={
    new HelloWorld().msg
}

say()
println getMsg()

調(diào)用groovy Hello.groovy 命令執(zhí)行該腳本,結(jié)果如下:

hello
hello world

當(dāng)然了,我們也可以寫一個(gè)單獨(dú)的HelloWorld類,帶上包名,然后在其它地方導(dǎo)包使用,就像Java那樣。有關(guān)于Groovy類的使用,我們后面還會(huì)講到,這里就不贅述了。
總結(jié)一下Groovy的類相比Java的一些不同,或者說是優(yōu)化的一些地方:

  • 表達(dá)式后面的分號是可選的
  • 每個(gè)類、構(gòu)造方法和方法默認(rèn)是public的
  • 在Groovy中,方法體中的最后一個(gè)表達(dá)式的值會(huì)被作為返回值。這意味著return語句是可選的
  • Groovy編譯器自動(dòng)加上getter/setter方法,所以不需要自己去書寫
  • 類的屬性可以通過點(diǎn)號來獲取,看起來好像它們在Java中是public的,在底層Groovy調(diào)用的是自動(dòng)生成的getter/setter方法。

6 閉包

閉包Closure,在Groovy中是很重要的一種數(shù)據(jù)類型。閉包實(shí)際上就是一段代碼塊,需要用{}包括起來。前面我們在講解一些例子的時(shí)候已經(jīng)用到了閉包,我們再來看一下閉包的結(jié)構(gòu)。

//定義一個(gè)閉包 ,記得要用{}包裹起來
def aClosure={
    int a,int b-> //-> 箭頭前面代表的是參數(shù),后面是執(zhí)行語句
    a+b  //返回值
}

println aClosure(1,2)

結(jié)果為 3。

閉包的參數(shù)類型也可以不指定,在運(yùn)行期有Groovy自動(dòng)推斷,比如下面這個(gè)例子,執(zhí)行起來也是沒有問題的

def bClosure={
     a,b->
    a+b
}

println bClosure(1,2)

閉包也可以沒有參數(shù)
如:

def aa={
    println "this is a Closure"
}
aa()

總結(jié)一下,閉包的類型有

1. def closureNama ={params -> code} 
2. def closureName= {code} 沒有參數(shù)的時(shí)候就沒有箭頭 ->

閉包的調(diào)用有兩種方式

1. 閉包對象.call(參數(shù))
2. 閉包對象(參數(shù))

如
aClosure(1,2)
aClosure.call(1,2)

需要注意一點(diǎn),閉包如果沒有參數(shù)的話,其隱含了一個(gè)參數(shù)是 it
和this的作用類似,代表的是傳入閉包的參數(shù)。比如:

def sayHello={"hello ${it}"}
println sayHello("Jim")

等同于
def sayHello={it->"hello ${it}"}

當(dāng)然了,如果閉包顯示的指明了無參數(shù),則在調(diào)用閉包的時(shí)候不能傳參數(shù),否則會(huì)報(bào)錯(cuò)。如

def noParams={->println "noParams"}
noParams();
//下面的代碼執(zhí)行會(huì)報(bào)錯(cuò)
//noParams(1)

閉包返回值
閉包總是會(huì)返回一個(gè)值。返回值是閉包的最后一條語句的值(如果沒有顯式的return語句),或者是可執(zhí)行的return 語句的值。如果閉包的最后一條語句沒有值就返回null。如之前舉得Hello.groovy中的例子:

def getMsg={
    new HelloWorld().msg
}

閉包作為方法參數(shù)
閉包也可以作為方法參數(shù),如:

int increment(Closure closure,int count){
    closure()+count
}
//斷言,如果為true就正常執(zhí)行,如果為false,就會(huì)報(bào)錯(cuò)
assert increment({1+1},1)==3

閉包委托
閉包代碼是在委托的閉包上執(zhí)行。默認(rèn)的,這個(gè)委托就是閉包的所有者。比如你在Groovy腳本中定義了一個(gè)閉包,那么所有者就是一個(gè)groovy.lang.Script實(shí)例。閉包的隱式變量delegate 允許你重新定義默認(rèn)的所有者。

例如:

class Test {
    def x = 30
    def y = 40

    def run() {
        def data = [ x: 10, y: 20 ]
        def cl = { 
            y = x + y 
        }
        cl.delegate = data
        cl.resolveStrategy = Closure.DELEGATE_FIRST
        cl()
        assert x == 30
        assert y == 40
        assert data == [x:10, y:30]
    }
}

new Test().run()

上面例子中閉包c(diǎn)1的委托變?yōu)閐ata,閉包的resolveStrategy在默認(rèn)情況下是OWNER_FIRST,即它會(huì)先查找閉包的owner(在本例中指的就是Test對象本身),如果owner存在,則在owner上執(zhí)行閉包中的代碼。這里我們將其設(shè)置成了DELEGATE_FIRST,即該閉包會(huì)首先查找delegate(本例中即data),如果找不到再去找owner。resolveStrategy還有其它的一些情況,具體的可以查看文檔中的例子,相信當(dāng)你看到這些例子后,會(huì)對閉包委托有一個(gè)清晰的認(rèn)識(shí)。

7 總結(jié)

限于篇幅和本系列的主題,本文簡單介紹了Groovy的一些語法和數(shù)據(jù)結(jié)構(gòu),這對于學(xué)習(xí)Gradle會(huì)有一些幫助。在后面Gradle的學(xué)習(xí)過程中,如果對Groovy的一些Api不熟悉可以查看Groovy的Api文檔,我們沒必要死記硬背這個(gè)Api,掌握學(xué)習(xí)的方法更加重要,對嗎?

下一篇,我們就正式進(jìn)入Gradle部分的學(xué)習(xí)了。

參考

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • Groovy :是一種動(dòng)態(tài)語言。 1:這種語言比較有特點(diǎn),它和 Java 一樣,也運(yùn)行于 Java 虛擬機(jī)中。簡單...
    PeytonWu閱讀 1,603評論 0 1
  • 這篇文章講給大家?guī)韌radle打包系列中的高級用法-自己動(dòng)手編寫gradle插件。我們平常在做安卓開發(fā)時(shí),都會(huì)在...
    呆萌狗和求疵喵閱讀 16,032評論 22 80
  • 導(dǎo)語: 隨著技術(shù)的發(fā)展,不管是前端開發(fā)、服務(wù)端開發(fā)或者是移動(dòng)端開發(fā)(移動(dòng)也是前端的一個(gè)分支)中都會(huì)用到自動(dòng)化構(gòu)建工...
    伊始雨深閱讀 3,058評論 0 4
  • 什么是 Groovy? 簡言之,Groovy是一種基于JVM(Java虛擬機(jī))的敏捷動(dòng)態(tài)開發(fā)語言。它是一種成熟的面...
    北緯26閱讀 4,169評論 0 14
  • 努力的人,應(yīng)該像好色那樣好學(xué) 做Android開發(fā)的同學(xué),對Gradle肯定不陌生,我們用它配置、構(gòu)建工程,可能還...
    HitenDev閱讀 13,480評論 9 50