Groovy的基礎文法
Groovy 的文法融合了 Ruby、Python 和 Smalltalk 的一些最有用的功能,同時保留了基于 Java 語言的核心文法。對于Java 開發人員,Groovy 提供了更簡單的替代語言,且幾乎不需要學習時間。
語句
Groovy的語句和Java類似,但是有一些特殊的地方。例如語句的分号是可選的。如果每行一個語句,就可以省略分号;如果一行上有多個語句,則需要用分号來分隔。
x = [1, 2, 3] println x y = 5; x = y + 7 println x assert x == 12
另外return關鍵字在方法的最後是可選的;同樣,傳回類型也是可選(預設是Object)。
動态類型
像其他Script一樣,Groovy 不需要顯式聲明類型。在 Groovy 中,一個對象的類型是在運作時動态發現的,這極大地減少了要編寫的代碼數量。在Groovy中,類型對于值(varibles)、屬性 (properties)、方法(method)和閉包(closure)參數、傳回值都是可有可無的,隻有在給定值的時候,才會決定它的類型,(當然聲明了類型的除外)。例如:
//Groovy 動态類型 myStr = "Hello World"
由于使用了動态類型,不需要繼承就可以得到多态的全部功能:
class Song{ Property length Property name }
class Book{ def public name def public author }
def doSomething(thing){ println "going to do something with a thing named = " + thing.name }
這裡定義了兩個Groovy 類,Song 和 Book。這兩個類都包含一個 name 屬性。函數 doSomething,它以一個 thing 為參數,并試圖列印這個對象的 name 屬性,但doSomething 函數沒有定義其輸入參數的類型,是以隻要對象包含一個 name 屬性,那麼它就可以工作。可見, Song 和 Book 的執行個體都可以作為 doSomething 的輸入參數。
mySong = new
Song(length:90, name:"Burning Down the House"
)
myBook = new
Book(name:"One Duck Stuck"
, author:"Phyllis Root"
)
doSomething(mySong) //prints Burning Down the House
doSomething(myBook) //prints One Duck Stuck
def doSth=this
.&doSomething
doSth(mySong)
doSth(myBook)
在例子的最後,我們還建立了doSomething的一個函數指針 doSth,最後的執行結果與調用doSoemthing是一樣的。
值得注意的是:與Groovy Beta不同,在使用新的JSR Groovy類時,類裡面的所有的變量都必須加上 def 關鍵字或者 private、protected 或 public 這樣的修飾符。當然,也可以用 @Property 關鍵字聲明成員變量。在Script中則不必。
字元串
Groovy中的字元串允許使用雙引号和單引号。
當使用雙引号時,可以在字元串内嵌入一些運算式,Groovy允許您使用 與 bash 類似的 ${expression} 文法進行替換。可以在字元串中包含任意的Groovy表達式。
name="James"
println "My name is ${name},'00${6+1}'"
//prints My name is James,'007'
Groovy還支援"uXXXX" 引用(其中X是16進制數),用來表示特殊字元,例如 "u0040" 與"@"字元相同。
大塊文本
如果有一大塊文本(例如 HTML 和 XML)不想編碼,你可以使用Here-docs. here-docs 是建立格式化字元串的一種便利機制。它需要類似 Python 的三重引号(""")開頭,并以三重引号結尾。
name = "James"
text = ""
“
hello
there ${name} how are you today?
”
""
assert text != null
println(text)
在Groovy-JSR中,不再支援下面這種多行字元串,個人覺得似乎與Here-docs功能重疊:
foo =
“hello
there
how are things?”
println(foo)
對字元串的操作
1. contains 字元串中是否包含子字元串,'groovy'.contains('oo')将傳回true;
2. count 傳回字元串中子字元串出現的次數,'groooovy'.count('oo')将傳回3.
3. tokenize 根據分隔符将字元串分解成子串,'apple^banana^grap'.tokenize('^')傳回['apple','banana','grape']。
4. 減操作 'groovy'-'oo',結果是'grvy'。
5. 乘操作 'oo'*3,結果是'oooooo'。
Groovy主要結構
接下來将展示Groovy的一些結構,包邏輯分支,類、閉包等等。
邏輯分支
if-else語句
Groovy提供Java相同的if-else語句。
x = false
y = false
if
( !x ) {
x = true
}
assert x == true if ( x ) { x = false } else { y = true } assert x == y
Groovy也支援三元操作符。
y = 5
x = (y > 1) ? "worked"
: "failed"
assert x == "worked"
switch語句
Groovy的switch語句相容Java代碼,但是更靈活,Groovy的switch語句能夠處理各種類型的switch值,可以做各種類型的比對:
1. case值為類名,比對switch值為類執行個體
2. case值為正規表達式,比對switch值的字元串比對該正規表達式
3. case值為集合,比對switch值包含在集合中,包括ranges
除了上面的,case值與switch值相等才比對。
x = 1.23
result = ""
switch
( x ) {
case
"foo"
:
result = "found foo"
// lets fall through
case
"bar"
:
result += "bar"
case
[4, 5, 6, ‘inList‘]:
result = "list"
break
case
12..30:
result = "range"
break
case
Integer
:
result = "integer"
break
case
Number
:
result = "number"
break
default
:
result = "default
"
}
assert result == "number"
Switch語句的工作原理:switch語句在做case值比對時,會調用isCase(switchValue)方法,Groovy提供了各種類型,如類,正規表達式、集合等等的重載。可以建立自定義的比對類,增加isCase(switchValue)方法來提供自定義的比對類型。
循環
while和do 循環
Groovy支援Java相同的while循環,但目前暫不支援do循環
x = 0
y = 5
while
( y-- > 0 ){
x++
}
assert x == 5
for循環
Groovy的for循環更簡單,而且能夠和各種類型的數組、集合、Map、範圍等一起工作,我們稍候會詳細介紹這些内容。
// iterate over a range
x = 0
for
( i in 0..9 ) {
x += i
}
assert x == 45
// iterate over a list
x = 0 for ( i in [0, 1, 2, 3, 4] ) { x += i }
assert x == 10
// iterate over an array array = (0..4).toArray() x = 0 for ( i in array ) { x += i }
assert x == 10
// iterate over a map
map = [‘abc‘:1, ‘def‘:2, ‘xyz‘:3] x = 0 for ( e in map ) { x += e.value }
assert x == 6
// iterate over values in a map x = 0 for ( v in map.values() ) {
x += v }
assert x == 6
// iterate over the characters in a string text = "abc" list = [] for (c in text) { list.add© } assert list == ["a" , "b" , "c" ]