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