為Java開發者解讀Groovy編程風格和語言特性

火星人 @ 2014-03-12 , reply:0


  

 

當一個Java開發人員加入到Groovy的開發之旅的時候,他/她經常帶著Java思想去思考,並逐步地學習Groovy,每次學習一個特性,這會讓他慢慢變得更有創造性和寫出更符合語言習慣的Groovy代碼。這篇文章的目的是引導這些開發人員去學習基本的Groovy編程風格,學習新的操作技巧,新的語言特性,例如閉包等等。這篇文章並不會詳細鋪開描述,而是給讀者一個入門的指引,並讓讀者在以後的深入學習打好基礎。如果你喜歡這篇文章,可以貢獻你的一份力量去豐富它。


無分號
C / C++ / C# / Java開發者,經常到處使用分號。儘管Groovy支持99%的java語法,有時你只需簡單的把java代碼粘貼到Groovy程序里,但是卻帶著一大堆分號。在Groovy里,分號是可選的,你可以省略他們,更常用的用法是刪除它們。
 

返回關鍵字 (Return) 變得可選
在Groovy的世界裡面,方法的程序塊結尾可以不寫'return'關鍵字而照樣返回值。尤其是對於語句不多的方法和閉包。這樣的寫法更優美更簡潔:

 
1 String toString() {return"a server"}

2 String toString() {"a server"}

但有些情況卻不那麼優美,例如你使用了變數,並在兩行裡面出現兩次:

 

1 def props() {

2 def m1 = [a:1, b:2]

3 m2 = m1.findAll { k, v -> v %2==0}

4 m2.c =3

5 m2

6 }

在這個例子裡面,或者是在最後一個表達式後面加上一個空行,抑或是顯式地加上'return'關鍵字會令代碼更有可讀性。

我自己個人習慣,有時候喜歡用return關鍵字,有時候又不喜歡,這跟個人口味有關係吧。但是,更多時候,例如在閉包裡面,我更喜歡不寫return關鍵字。所以即使return關鍵字是可選的,也不會強制你不能使用它,如果你認為它會打破代碼的可讀性。
 

謹慎為上,然而當你使用def關鍵字定義,而並非用代替具體某一個類型去定義的方法,有時候你會驚奇的發現最後一條表達式會作為返回結果而返回。所以更多時候更推薦使用具體的類型(例如void或類型)作為返回類型。在我們上面的例子中,如果我們忘記了把m2放在最後一行並作為返回值,那麼最後的一個表達式將是m2.c = 3,這樣會導致數值3作為返回值返回,而不是我們期待的結果。

形如if/else語句,try/cath語句同樣可以返回值,因為它們裡面都有"最後一個表達式"會被返回。

01 def foo(n) {

02 if(n ==1) {

03 "Roshan"

04 }else{

05 "Dawrani"

06 }

07 }

08  

09 assertfoo(1) =="Roshan"

10 assertfoo(2) =="Dawrani"

 
 

Def 和 類型

當我們討論def和類型,我經常會發現一些開發人員既用'def'又用類型。但是'def'在這裡是多餘的。所以,大家要做一個選擇,要不用'def', 要不就用類型。

所以不要寫出如下的代碼:

1 def String name = "Guillaume"

可以寫成
1 String name ="Guillaume"

當我們在Groovy裡面使用def,真正的類型是Object(所以你可以向用def定義的變數,賦值任何的對象,並且,當一個方法是用def作為返回值的時候,可以以任何對象類型作而返回)。
當一個方法未聲明變數類型,你可以使用def,但是這不是必須的,所以可以省略他,所以可以代替下面的語句:

1 void doSomething(def param1, def param2) { }

推薦:
1 void doSomething(param1, param2) { }

但是,就如我們在文章末尾提到的,我們更推薦為方法的參數指定類型。這樣可以幫助提高代碼的可讀性,也可以幫助IDE工具使代碼完整,或者利用Groovy的靜態類型檢查或靜態編譯功能。
另外一個def多餘的地方是定義構造函數,應避免使用:

1 class MyClass {

2 def MyClass() {}

3 }

應去掉 構造函數前的'def':
1 classMyClass {

2 MyClass() {}

3 }
 

默認的Public

默認情況,Groovy會認為類和方法是定義為'public'的。所以你不需要顯式的聲明public。當需要聲明為非public的時候,你需要顯式的指定修飾符。

所以避免如下寫法:

1 public class Server {

2 public String toString() {return "a server"}

3 }

推薦使用如下簡潔的寫法
1 class Server {

2 String toString() {"a server"}

3 }

你可能會關心包範圍內的可訪問性問題。事實上,Groovy允許省略public, 是因為這個包範圍裡面默認情況下是不支持public,但是事實上有另外一個Groovy註釋語法去實現可訪問性:
1 class Server {

2 @Package ScopeCluster cluster

3 }
 

省略圓括弧

Groovy允許你在頂級表達式中省略圓括弧,例如println語句:

1 println"Hello"

2 method a, b

對比:
1 println("Hello")

2 method(a, b)

當方法的最後一個參數是閉包的時候,例如使用Groovy的'each'迭代機制,你可以把閉包放在括弧之外,甚至省略括弧:
1 list.each( { println it } )

2 list.each(){ println it }

3 list.each { println it }

通常我們推薦使用上面第三種寫法,它顯得更自然,因為沒有圓括弧是多麼的多餘!
但是Groovy在某些情況並不允許你去掉圓括弧。就像我之前說的,頂級表達式可以省略,但是嵌套的方法或者賦值表達式的右邊,你卻不能省略:

1 def foo(n) { n }

2  





[火星人 via ] 為Java開發者解讀Groovy編程風格和語言特性已經有98次圍觀

http://www.coctec.com/docs/program/show-post-71303.html