學習Groovy的特性
翻譯自 http://sysgears.com/articles/groovy-differences-java/
Groovy基于jvm,是一種面向對象的動態語言。如果你需要編寫輕量級的腳本并且想要從Java的生態環境中獲益,那么Groovy對于你來說是再合適不過的候選者。Groovy動態得被編譯成字節碼,并且兼容大部分的Java類庫。同時Groovy非常易于學習,因為在Groovy中Java的語法都是有效的。但還是有些注意事項需要你在開始編程之前了解的。這篇文章展現了Groovy的一些特性并提供了一些幫助你編寫清晰,groovy-style代碼的建議。
Groovy beans
聲明Groovy beans是非常簡單的。典型的Java bean需要包含構造方法,私有屬性和getter / setter 方法。Groovy bean僅僅需要field,getter / setter 方法會被隱式得創建。
class User {
String firstName // bean field
String lastName // bean field
}
def user = new User()
user.firstName = "John"
user.lastName = "Doe" user.firstName和user.lastName會調用setter方法完成任務。如果有必要的話你也可以為field聲明自定義getter / setter 方法。下面舉個例子:
class User {
String firstName
String getFirstName() {
"The first name is $firstName"
}
void setFirstName(String firstName) {
this.firstName = "[$firstName]"
}
// ...
}
user.firstName = 'John'
println user.firstName {}中的內容通過setter方法添加,"the first name"后面通過getter方法得到。結果是這樣:
The first name is [John]
如果為field設置了訪問修飾符,那就僅僅創建了field,getter / setter方法不會被自動創建。
Groovy 閉包
Groovy提供了一種創建方法為一等對象的方式————Groovy 閉包。使用閉包,你能夠定義代碼塊并且傳遞參數,就像它是常規變量一樣。
// the simplest closure
def hello = {"Hello, $it!"}
assert hello('Chris') == 'Hello, Chris!'
// the closure that do not take any params
def bye = {->'Bye!'}
assert bye() == 'Bye!'
// the closure with several params
def niceHello = {firstName, lastName -> "Hello, $firstName $lastName!"}
assert niceHello('Chris', 'Bennett') == 'Hello, Chris Bennett!' 如上所示,閉包默認持有一個it參數,你可以指定可命名的參數改變這一默認行為。或者聲明{-> ...}省略參數。
Groovy list和map
Groovy 為lists和Maps提供了內建的支持,并且允許用類似于JavaScript的方式初始化和操作數據結構。首先,讓我們看一眼List的實現,我們可以只用兩個[]創建一個空的List。
// an empty list def emptyList = [] // predefined list def list = ['One', 'Two', 'Three']
或者從List中取出一個或多個元素。
def list = ['One', 'Two', 'Three'] // gets the first element from the list assert list[0] == 'One' // gets a range of elements from the list assert list[1..2] == ['Two', 'Three'] // gets another range assert list[-1..-2] == ['Three', 'Two']
另外為迭代和轉化lists提供了一系列可用的便捷操作:
// iterates the list
def emptyList = []
list.each {emptyList << "$it!"}
assert emptyList == ['3!', '1!', '2!']
// iterates the list and transforms each entry into a new value
// using the closure
assert list.collect {it * 2} == [6, 2, 4]
// sorts using the closure as a comparator
assert list.sort {it1, it2 -> it1 <=> it2} == [1, 2, 3]
// gets min or max using closure as comparator
assert list.min {it1, it2 -> it1 <=> it2} == 1 Map的實現也有很多的語法糖。可以通過[]和:聲明一個空的map:
// an empty map def emptyMap = [:] // predefined map def map = [John: 10, Mark: 20, Peter: 'Not defined']
兩種風格獲取Map的值————bean風格或者數組風格
def map = [John: 10, Mark: 20, Peter: 'Not defined']
// the array style
assert map['Peter'] == 'Not defined'
// the bean style
assert map.Mark == 20
// also you can preset default value that will be returned by
// the get method if key does not exist
assert map.get('Michael', 100) == 100 借助閉包實現迭代和轉換:
// iterates the map
def emptyMap = [:]
def map = [John: 10, Mark: 20, Peter: 'Not defined']
map.each { key, value ->
emptyMap.put key, "$key: $value" as String
}
assert emptyMap == [John: 'John: 10', Mark: 'Mark: 20',
Peter: 'Peter: Not defined']
// iterates the map and transforms each entry using
// the closure, returns a list of transformed values
assert map.collect { key, value ->
"$key: $value"
} == ['John: 10', 'Mark: 20', 'Peter: Not defined']
// sorts map elements using the closure as a comparator
map.put 'Chris', 15
assert map.sort { e1, e2 ->
e1.key <=> e2.key
} == [John: 10, Chris: 15, Mark: 20, Peter: 'Not defined'] 其他有用的
-
boolean操作符==和Java中的equals相同效果,并且不區分類型。不像Java中==意味著基本類型相等和對象地址相等。如果你要比較對象的地址,使用is方法:
assert [] == [] assert ![].is([])
-
.*操作符被引入用于表示在集合內所有的成員上執行操作:
assert [1, 2, 3] == ['a', 'ab', 'abc']*.size()
-
在方法的末端return是可選的:
def foo() { // do something return something } // is equals to def bar() { // do something something }
結語
Groovy還有很多有趣的特性:元編程,函數式編程,AST轉換。在學習的路途上你一定會發現它們。Groovy的強大之處在于,你可以用基本的Java語法開始,然后逐步學習并且改進代碼直到它們真正意義上的靈活和動態。