學習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語法開始,然后逐步學習并且改進代碼直到它們真正意義上的靈活和動態。