1. 程式人生 > >Gradle系列第(一)篇---Groovy語法初探

Gradle系列第(一)篇---Groovy語法初探

一、從Java到Groovy的關係

Groovy能直接接受你的Java程式碼,也就是說在Groovy中寫java程式碼也是可以的,因為Groovy 是一門JVM 語言,也就是,Groovy 的程式碼最終也會被編譯成JVM 位元組碼,交給虛擬機器去執行,我們也可以直接反編譯這些位元組碼檔案。從一段你很熟悉的程式碼開始,在迴圈中列印三遍hello java。

    public  void  printHello() {
        for (int i = 0; i < 3; i++) {
            System.out.println("hello java");
        }
    }

那麼改成Groovy語言改如何寫呢?其實有多種寫法。
a、第一種

    for  ( i  in  0..2 ) {
        println("hello Groovy")
     }

b、第二種

   3.times {
        println("hello Groovy")
    }

c、第三種

   0.upto(2) {
        println("hello Groovy")
    }

d、第四種

    List list = ["hello Groovy", "hello  Groovy", "hello  Groovy"
] list.each {element-> println(element) }

上面四種方法的輸出結果都是 hello Groovy ,groovy 的方法呼叫是可以沒有括號的,而且也不需要分號結尾。可以見到相對java來說,Groovy語言要稍微簡潔一點,但是現在看起來可能有點蒙逼了。下面簡單地說一下 groovy 一些語法。

二、Groovy語法

1、變數

有兩類可以在生成指令碼中宣告的變數: 區域性變數和額外屬性。 在groovy 中,沒有固定的型別,區域性變數是用def關鍵字宣告的。它們只在定義它們的範圍內可以被訪問,比如:

def
name = 'Jerry'

變數定義時,也可以直接指定型別,比如

def  int x = 1   

我們通過單引號引用一串字串的時候這個字串只是單純的字串,內容嚴格對應Java中的String,不對使號的話,則它會對$表示式先求值。

def name1 = 'Jerry'
def name2="Lisa ,$name1" //name2實際就是Lisa,Jerry

上面屬於區域性變數,再看看額外屬性,Gradle 的域模型中,所有增強的物件都可以容納使用者定義的額外的屬性。這包括但並不限於專案(project)、任務(task)和原始碼集(source set)。額外的屬性可以通過所屬物件的ext屬性進行新增,讀取和設定。或者,可以使用ext塊同時新增多個屬性。比如:

task myTask{
    ext.myProperty="value"
}

這表示為myTask建立了一個名字為myProperty屬性,值是value

2、方法

類似 python 一樣,通過def關鍵字定義一個方法。無型別的函式定義,必須使用def關鍵字,方法如果不指定返回值,預設返回最後一行程式碼的值。

def getNum(def num) {
    num * num
}

//如果指定了函式返回型別,則可不必加def關鍵字來定義函式
int  getNum(def num){
     num * num
}

getNum(2)的返回值就是4, 函式定義時,引數的型別也可以不指定。比如

def getNum(num) {
    num * num
}

上面每一行程式碼都不需要加上分號,除了每行程式碼不用加分號外,Groovy中函式呼叫的時候還可以不加括號。比如:

println("test") ---> println "test"

雖然對於函式呼叫可以不帶括號,但是Groovy經常把屬性和函式呼叫混淆。所以我覺得加上更好。

3、類
class People{
    List hobby=['swim','play','watch TV']
    String name="Jerry"
      int  getAge(){
        return 20
    }
}

在Groovy 中,預設所有的類和方法都是pulic的,所有類的欄位都是private的;和java一樣,我們通過new關鍵字得到類的例項,使用def接受物件的引用:def people = new People(),而且在類中宣告的欄位都預設會生成對應的setter,getter方法。所以我們可以people.getName()來取值,也可以使用people.name來取值,同時我們可以使用people.setName ‘Lisa ,注意,groovy 的方法呼叫是可以沒有括號的,而且也不需要分號結尾。除此之外,我們也可以直接呼叫;

4、資料型別

Groovy的資料型別主要有三大類,一個是Java中的基本資料型別,一個是Groovy中的容器類,還有一個非常重要的是閉包。

a、基本資料型別
Groovy世界中的所有事物都是物件。所以int,boolean這些Java中的基本資料型別,在Groovy程式碼中其實對應的是它們的包裝資料型別。比如int對應為Integer,boolean對應為Boolean。

b、Groovy中的容器類
- List:連結串列,其底層對應Java中的List介面,一般用ArrayList作為真正的實現類。
- Map:鍵-值表,其底層對應Java中的LinkedHashMap。
- Range:範圍,它其實是List的一種拓展。

在 Groovy 中,定義一個列表是這樣的:

List list = [1, 2, 3, 4, 5]
list[2]=100
println list.size 

assert list[2] == 7 //獲取下標為2的值
assert list instanceof java.util.List //型別為java.util.List
def list2 = new ArrayList<String>(list1) //建立新集合
def list3 = ['a', 1, 'a', 'a', 2.5, 2.5f, 2.5d, 'hello', 7g, null, 9 as byte] //可以不同型別,並且可以重複,可以為null

如何定義一個Map呢?

def mymap = ['key1':'value1','key2':true] 

map的取值是這樣

mymap.key1   或者mymap[key1]  

Range是Groovy對List的一種拓展,變數定義和大體的使用方法如下:

def range = 1..5  

實際上包括 1,2,3,4,5這五個值,這在上面的迴圈中已經用到過。又比如:

def range = 5..8;  //建立左右包含的Rangerange = 5..<8; //不包含8,小於8

c、閉包(Closure)

閉包(Closure)是一種強大的資料型別,對閉包比較書面的一種解釋“閉包是可以用作函式引數和方法引數的程式碼塊”。其實Groovy的閉包更象是一個“程式碼塊”或者方法指標,程式碼在某處被定義然後在其後的呼叫處執行。簡單點說就是代表了一段可執行的程式碼。其外形如下:

def xxx = {paramters -> code}  //或者  
def xxx = {無引數,純code}  這種情況不需要->符號

比如這就是很簡單的閉包:

def myClosure={
    println("Hello")
}

呼叫方式:myClosure()

接受引數的閉包:

def myClosure={String str->
    println(str)
}
呼叫方式:myClosure("Hello")

接受多個引數的閉包:

def myClosure={String str,int num->
    println("$str  ,$num ")
}
呼叫方式:myClosure("Hello",20)

閉包裡面的引數型別可以省略不寫:

def myClosure={ str, num->
    println("$str  ,$num ")
}
呼叫方式:myClosure("Hello",20)

如果閉包沒定義引數的話,則隱含有一個引數,這個引數名字叫it,和this的作用類似。it代表閉包的引數:

def list = [1,2,3,4,5]  //定義一個List
list.each{  //呼叫它的each函式
      println it
}

閉包在Groovy中大量使用,比如很多類都定義了一些函式,這些函式最後一個引數都是一個閉包,閉包有點回調函式的感覺。
最後:GroovyAPI:http://www.groovy-lang.org/api.html