1. 程式人生 > >Groovy學習筆記(二):Groovy的基本語法

Groovy學習筆記(二):Groovy的基本語法

1、Java和Groovy對比

1.1、Hello Groovy!

從一個簡單的案例開始:

class A01_GroovyApp {

    public static void hello() {
        println('Hello Groovy!')
    }

    public static void main(String[] args) {
        hello()
    }
}

執行結果

Hello Groovy!

1.2、如何實現迴圈

簡單的,可以類似Java一樣這樣寫:

Stream.of(1, 2, 3, 4)
        .
forEach(new Consumer<Integer>() { @Override void accept(Integer integer) { println("Java print" + integer) } })

執行結果

Java print1
Java print2
Java print3
Java print4

也可以這樣寫

for (i in 0..4)  {    //方式1
    print "$i"
}

println()

0.upto(4) { print "$it" }  //方式2
println() 3.times { print("$it") } //方式3 println() 0.step(10, 2) { print("$it") } //方式4

執行結果:

01234
01234
012
02468

1.3、初識GDK

Java中,假如我們想要在程式碼中呼叫SVN的help,我們應該這樣實現Java程式碼:

SVN_Java.png

在groovy中,我們只需要這樣實現:

println "svn help".execute().text

//或者執行 groovy -v命令查詢groovy的版本
println "groovy -v".execute
().text //或者執行 ls -l命令 println "ls -l".execute().text

結果:

java.lang.UNIXProcess

Groovy Version: 2.4.15 JVM: 1.8.0_131 Vendor: Oracle Corporation OS: Mac OS X

total 128
-rw-r–r– 1 qing.mei staff 23 Mar 29 20:11 A00_Helloworld.groovy
-rw-r–r– 1 qing.mei staff 232 Apr 4 20:04 A01_GroovyApp.groovy
-rw-r–r– 1 qing.mei staff 50 Mar 29 20:29 A02_GroovyScript.groovy
-rw-r–r– 1 qing.mei staff 383 Apr 4 20:09 A03_foreach.groovy
-rw-r–r– 1 qing.mei staff 114 Mar 30 17:33 A04_GDK.groovy
-rw-r–r– 1 qing.mei staff 93 Mar 30 19:27 A05_Exception.groovy
-rw-r–r– 1 qing.mei staff 250 Mar 30 19:29 A06_Wizard.groovy
-rw-r–r– 1 qing.mei staff 29 Mar 30 19:29 A06_Wizard_Script.groovy
-rw-r–r– 1 qing.mei staff 125 Mar 30 19:36 A07_GroovyBean.groovy
-rw-r–r– 1 qing.mei staff 188 Mar 30 19:36 A07_GroovyBean_Script.groovy
-rw-r–r– 1 qing.mei staff 387 Mar 30 19:36 A07_JavaBean.java
-rw-r–r– 1 qing.mei staff 299 Apr 4 19:25 A08Calendar.groovy
-rw-r–r– 1 qing.mei staff 188 Apr 4 19:33 A09Robot.groovy
-rw-r–r– 1 qing.mei staff 200 Apr 4 19:31 A09RobotScript.groovy
-rw-r–r– 1 qing.mei staff 524 Apr 4 19:44 A10Params.groovy
-rw-r–r– 1 qing.mei staff 1540 Apr 4 20:01 A11MultipleAssignments.groovy

2、JavaBean

相比Java的get和set方法,我們來看Groovy的JavaBean:

class A07_GroovyBean {

    def name = 'qingmei2'
    final year

    A07_GroovyBean(year) {
        this.year = year
    }
}

其操作方式:

def groovyBean = new A07_GroovyBean(10)

println "year: $groovyBean.year"
println "name: $groovyBean.name"
println 'Setting...'
groovyBean.name = "LiHua"
println "name: $groovyBean.name"

執行結果:

year: 10
name: qingmei2
Setting…
name: LiHua

同時,還可以這樣節省程式碼:

//我們可以這樣代替Java的Calendar.getInstance()
Calendar.instance

str = 'hello'

//謹慎使用class屬性,類似Map/生成器等一些類對該屬性有特殊處理,因此為了避免意外,一般使用getClass()
def name = str.class.name

println "the string = $str"
println "the string class name = $name"

3、靈活初始化和具名引數

Groovy中可以靈活地初始化一個JavaBean類。在構造物件時,可以簡單地以逗號分隔的名值對來給出屬性值。如果類有一個無參構造器,該操作會在構造器之後執行。1也可以設計自己的方法,使其接受具名引數。要利用這一特性,需要把第一個形參定義為Map。下面通過程式碼來實際地看一下。

class A09Robot {

    def type, height, width

    def access(Map location, weight, fragile) {
        println "received fragile ? $fragile, weight: $weight, location: $location"
    }
}
def robot = new A09Robot(type: 'arm', width: 10, height: 40)
println "$robot.type, $robot.width, $robot.height"

robot.access(x: 30, y: 20, z: 10, 50, true)
robot.access(50, true, x: 30, y: 20, z: 10)

我們來看結果:

arm, 10, 40
received fragile ? true, weight: 50, location: [x:30, y:20, z:10]
received fragile ? true, weight: 50, location: [x:30, y:20, z:10]

4.可選形參

參考Kotlin,我們可以給函式的引數設定預設的值:

//groovy 可以把方法和構造器形參設定為可選擇的
//但是這些形參必須位於形參列表的末尾
def log(x, base = 10) {
    Math.log(x) / Math.log(base)
}

println log(1024)
println log(1024, 10)
println log(1024, 2)

//同時,groovy還會把末尾的陣列形參視作可選的
//因此,可以為最後一個形參提供0個或者多個值
def task(name, String[] details) {
    println "$name - $details"
}

task 'call', '123-456-7890'
task 'call', '123-456-7890', '234,567,890'
task 'checkmail'

結果:

3.0102999566398116
3.0102999566398116
10.0
call - [123-456-7890]
call - [123-456-7890, 234,567,890]
checkmail - []

5.使用多賦值

向方法傳遞多個引數,這在很多程式語言中都司空見慣。但是從方法返回多個結果,儘管可能非常實用,卻不那麼常見。

要想從方法返回多個結果,並將它們一次性賦給多個變數,我們可以返回一個數組,然後將多個變數以逗號分隔,放在圓括號中,置於賦值表示式左側即可。

後面的例子中有一個負責將全名分割為名字(FirstName)和姓氏(LastName)的方法。不出所料,split()方法就返回一個數組。可以把splitName()的結果賦給一對變數:firstName和lastName。Groovy會把結果中的兩個值分別賦給這兩個變數。

def splitFullName(String fullname) {
    fullname.split ' '
}

def (firstname, lastname) = splitFullName('James Bond')

println "$lastname, $firstname $lastname"

結果:

Bond, James Bond

還可以使用該特性來交換變數,無需建立中間變數來儲存被交換的值,只需將欲交換的變數放在圓括號內,置於賦值表示式左側,同時將它們以相反順序放於方括號內,置於右側即可。

//交換值的方式

def name1 = 'name1'
def name2 = 'name2'

println "$name1 and $name2"

(name1, name2) = [name2, name1]

println "$name1 and $name2"

結果:

name1 and name2
name2 and name1

此外,當變數與值的數目不匹配時,如果有多餘的變數,groovy會把它們設定為null,多餘的值則會被丟棄:

//仍然是上面的名字分割案例
def (names) = splitFullName('James Bond')
println "$names"

//左側只有兩個變數,因此Spike和Tyke會被丟棄
def (String cat, String mouse) = ['Tom', 'Jerry', 'Spike', 'Tyke']
println "$cat and $mouse"

def (String first, String second, String third) = ['Tom', 'Jerry']
println "$first and $second and $third"

結果:

James //多餘的值則會被丟棄
Tom and Jerry
Tom and Jerry and null //多餘的變數,groovy會把它們設定為null