程式扎記: [ GroovyTutr ] Begginner Tutorial 1 - Getting started

標籤

2013年12月15日 星期日

[ GroovyTutr ] Begginner Tutorial 1 - Getting started

參考自 這裡 與 淺談 Groovy 與 Gradle 
Preface: 
Groovy 是 Java 平台上設計的物件導向編程語言。這門動態語言擁有類似Python、Ruby和Smalltalk中的一些特性,可以作為Java平台的腳本語言使用. Groovy的語法與Java非常相似,以至於多數的Java代碼也是正確的Groovy代碼。Groovy代碼動態的被編譯器轉換成Java位元組碼。由於其運行在JVM上的特性,Groovy可以使用其他Java語言編寫的庫. 如果一樣的功能能夠使用較少的 code 來撰寫, 那等同生產力能夠提升. 下面是來自於 http://Groovy.CodeHaus.org 的一個範例程序: 
  1. package demo  
  2.   
  3. class Foo {  
  4.   void doSomething() {  
  5.     def data = ["name""James""location""London"]  
  6.     for (e in data) {  
  7.       println("entry ${e.key} is ${e.value}")  
  8.     }  
  9.   }  
  10.   
  11.   void closureExample(collection) {  
  12.     collection.each { println("value ${it}") }  
  13.   }  
  14.   
  15.   static void main(args) {  
  16.     def values = [123"abc"]  
  17.     def foo = new Foo()  
  18.     foo.closureExample(values)  
  19.     foo.doSomething()  
  20.     def printSum = { a, b -> print a+b }  
  21.     printSum( 57 )  
  22.   }  
  23. }  
從上面代碼可以發現下面幾件事: 
* public 關鍵字不再需要 (預設就是 public)
* Groovy 為弱型態語言, 使用 def 關鍵字來代表所有的物件.
* Groovy 支援 Closure
* 結尾的 ";" 已經不需要

更多的 Groovy 特色會在後續一一介紹. 

Setting up your Groovy environment: 
在安裝 Groovy 的開發環境前, 請先確認 JRE/JDK 已經安裝, 接著到 這裡 下載 Installer 安裝或者按照下面步驟安裝 .zip 檔: 
1. Get a copy of the Groovy distribution from the website, and copy it to some place on your hard drive.
2. Unzip the groovy archive to some logical place on your hard drive, I have mine in C:\dev\groovy-2.0.5
3. Set the GROOVY_HOME environment variables. On Windows, follow these steps:
3.1 Optionally add a new System variable with the name GROOVY_HOME and the value of the directory groovy was installed in (mine is C:\Groovy\Groovy-2.2.1)
3.2 Start a command prompt, and type "echo %GROOVY_HOME%" and hit return to see that your environment variables were set correctly.

4. Optionally add %GROOVY_HOME%\bin to your system path
5. Try opening groovyConsole.bat by double clicking on the icon in the bin directory of the Groovy distribution.

我的第一個 Groovy - Hello, World: 
Java 常為 script language 詬病的就是雖然我只是要 print 個 Hello word, 還是需要建立一個 class, 然後打上許多的代碼才能夠完成入門的 "Hello word". Groovy 則相對方便: 
 
什麼, 這是 Java 的 code 嗎? 怎麼不用宣告 class 了! 而且更方便的是當你要 print 時, 連 "system.out" 都省了. 而許許多多 Groovy 的特性讓你不但能保留 Java 的優點, 而且能以生產力較高的 script 語言的語法進行開發. (在 groovyConsole UI 中, 要執行代碼請按 CTRL+R

除了 groovyConsole 之外, Groovy 也提供與 Python 類似的 shell console, 讓你可以在命令提示字元後輸入代碼並執行之: 
 

Variables: 
在一開頭我們提到了 Groovy 是一個弱型態語言, 而且它與 Javascript, Python 等 script 語言一樣, 也提供了許多對變數操作便利的 operators 與 conventions: 
 

其中值得注意的是: 
  1. x = "John"  
  2. println "Hi, $x"  
沒想到在字串中能自動辨識變數 "$x", 這也讓我們省掉一堆的 "+" 來串接字串與變數! 

Lists and Maps: 
Groovy language 預設支援兩種重要的資料結構類型: lists 與 maps (lists 其實就是 Java 的 ArrayList). 而你可以如下初始化 lists 與 maps: 
  1. emptyMap = [:] // 初始化 maps  
  2. emptyList = [] // 初始化 lists  
底下是 lists 的操作範例: 




















底下是 maps 的操作範例: 
 

Range: 
除了 lists 與 maps 外, Groovy 還支援一個相當方便的功能: Range. 透過他你可以很方便地寫出跟 Python 一樣簡潔的 for-loop: 
  1. for (i in 1..5)  
  2. {  
  3.     print "$i"  
  4. }  
  5. println ""  
  6. (1..5).each {print it}  
執行結果: 
12345
12345

More Convenient way: 
接著我們來看看 Groovy 還提供什麼語法蜜糖可以讓我們少寫些代碼. 假設你有段代碼如下: 
  1. def app = new Application();  
  2. def server = new Server();                
  3.       
  4. server.name = app.name;  
  5. server.status = "Test";  
  6. server.sessionCount = 3;  
  7. server.start();  
  8. server.stop();  
透過每個類別都有的 with 函數, 你可以傳進一個 closure. 因此你可以改寫成: 
  1. server.with {  
  2.     name = app.name  
  3.     status = "Test";  
  4.     sessionCount = 3  
  5.     start()  
  6.     stop()  
  7. }  
還不夠清楚? 再來看一個範例. 假設你有代碼如下: 
  1. Calendar calendar = Calendar.getInstance();  
  2. calendar.clear();  
  3. calendar.set(Calendar.MONTH, Calendar.JULY);  
  4. calendar.set(Calendar.DATE, 4);  
  5. calendar.set(Calendar.YEAR, 1776);  
  6. Date time = calendar.getTime();  
  7. System.out.println(time);  
則在 Groovy 的世界你可以使用更簡潔的寫法: 
  1. def calendar = Calendar.instance  
  2. calendar.with {  
  3.     clear()  
  4.     set MONTH, JULY  
  5.     set DATE, 4  
  6.     set YEAR, 1776  
  7.     println time  
  8. }  
至於什麼是 Closure, 之後的 Post 更深入去介紹它. 接著如果你覺得還不方便, 考慮常用的 ArrayList, 你可以使用類似匿名的方式 import 如下: 
  1. import java.util.ArrayList as Alist  
接下來要使用 ArrayList 便可以如下 new 一個物件: 
  1. def list = new Alist();  
再來透過 Groovy 讓你的 Code 更安全了, 參考代碼如下: 
  1. def srv = null;  
  2. if(srv.name.equals("Test"))  
  3. {  
  4.     srv.start();  
  5. }  
很直覺的這會引發 java.lang.NullPointerException. 因此通常我們會這麼寫: 
  1. def srv = null;  
  2. if(srv!=null && srv.name.equals("Test"))  
  3. {  
  4.     srv.start();  
  5. }  
但這實在是不方便, Groovy 新增了一個 operator "?." (Safe Navigation Operator) 讓你可以改寫上面的判斷式為: 
  1. if(srv?.name.equals("Test"))  
  2. {  
  3.     srv.start();  
  4. }  
此時即使 srv 為 null, 也不會觸發 java.lang.NullPointerException! 下面是該 operator 的另一個改寫例子: 
 

More Strong/Improvement Point: 
Groovy 支援所謂的 Operator overriding. 考慮有個類別定義如下: 
  1. class Complex {  
  2.     def re;  
  3.     def im;  
  4.       
  5.     def plus(th){ new Complex(re:re+th.re, im:im+th.im);}     
  6.     def minus(th) {new Complex(re:re-th.re, im:im-th.im);}  
  7.     String toString(){ "$re + $im j" }  
  8. }  
如果你要實現複數相加的結果, 你可能如下這樣做得到 cx3=cx1+cx2
  1. def cx1 = new Complex(re:1,im:2)  
  2. def cx2 = new Complex(re:4,im:8)  
  3. def cx3 = new Complex(re:cx1.re+cx2.re, im:cx1.im+cx2.im)  
  4. println "$cx3" // 5 + 10 j  
事實上你可以這麼幹 (你已經 Override operator "+ "-"): 
  1. def cx3 = cx1+cx2;  
  2. def cx4 = cx1-cx2;  
  3. println "\$cx3=$cx3; \$cx4=$cx4";  
執行結果為: 
$cx3=5 + 10 j; $cx4=-3 + -6 j

Supplement: 
Groovy User Guide 
Getting Groovy With "with"

沒有留言:

張貼留言

網誌存檔

關於我自己

我的相片
Where there is a will, there is a way!