天天看點

Groovy學習筆記-基礎

作為一個近乎渣渣的七年經驗程式員,回鄉我的新工作竟然又是一門新語言和新架構。能學一點是一點吧。

 <hr> 

跟着Grails Getting Started-II這本書的流程學

1、建立項目

我在F盤建立了一個web目錄

然後在web目錄下create-app racetrack

然後Grails幫我在web目錄下建立了一個項目叫racetrack

這時候我把指令行cd到racetrack目錄下,輸入grails run-app

程式就能運作起來了

2、建立MVC

domain就是M

指令行輸入grails create-domain-class Race,grails create-domain-class Registration

    Grails幫我在domain/racetrack檔案夾下建立Race.groovy,Registration.groovy檔案

    我照書上給這倆類添加了一些屬性

清單(list)映射(map)範圍(range) 是引用其他對象的集合,前兩個引用對象,後一個引用整型值。他們都能動态增長,清單通過整型值索引,映射用任意類型值索引。

清單(list)

def numbers = [11,12,13,14] 索引可以使用負數,表示從末端開始向前。 numbers[3]實質上就是numbers.getAt(3)

numbers[0..2]  //傳回清單[11,12,13],表示包含邊界的索引範圍 numbers[0..<2]  //傳回清單[11,12],表示不包含邊界的索引範圍

通過<<運算符可以把一個新元素追加到清單的最後 使用+運算符可以連接配接兩個清單 numbers+[15,16]  //傳回清單[11,12,13,14,15,16] -操作符從清單中删除元素 numbers-[13]  //傳回清單[11,12,14]

清單的方法 add :一個參數是在末尾追加新值,兩個參數的話第一個參數指定位置 addAll: contains:如果該清單包含指定值就傳回true get:傳回目前清單中指定位置的元素值 isEmpty:如果目前清單沒有元素傳回true remove:删除指定的元素,參數可以是下标,也可以是首次出現的給定元素,當元素是數值型時,不能通過元素删除,會出現越界異常(out-of-bound)

size,傳回一個整數,表示元素個數

以下是GDK新增 flatten:使目前清單元素形式一緻并傳回一個新清單 getAt:和get一個樣,這個是GDK新增的,差別隻是這個能複數索引,能通過範圍傳回新清單 intersect:傳回一個新清單,其值為原始清單和輸入清單的所有元素 leftShift:重載左移運算符,提供一個像清單添加新值得簡單方法 minus:生成一個新清單,元素由原始清單中那些不包含在參數collection中的值組成 plus:生成一個新清單,參數可以是值也可以是清單 pop:删除目前清單中最後一個值元素 putAt:指派語句支援下标運算符 reverse:傳回原清單倒序 sort:傳回原始清單排序副本

映射(map)

一種引用對象的無序集合,映射中元素可以根據關鍵字通路,關鍵字可以是任意類型,映射的值可以為空。 範例: ['Ken':'Barclay','John':'Savage']          姓/名集合 [4:[2],6:[3,2],12:[6,4,3,2]]                       整形關鍵字及其約數清單 [:]                                                          空映射 如果關鍵字是變量名,就解釋成String def x=1 def y=2 def m = [x : y , y : x] 于是m就是映射: m=['x' : 2, 'y' : 1]

映射中增加一個元素如下 library['Sally']=['Basic']

映射的方法: containsKey: get:根據Key找Value,第二個參數可選,可以放預設值,如果沒有找到對應的key則傳回預設值,沒放預設值得話,沒找到傳回空。 keySet:傳回目前映射的一組關鍵字(Set類型),可以用來周遊映射。 getAt: put:第一個參數放Key,第二個參數放Value,都是對象類型。 size: values:傳回目前映射中所有值得結合,類型是Collection

範圍(range)

範圍是表達特定序列值得簡略方法。通過雪烈中第一個值和最後一個值表示,範圍可以是倒序,也可以用<表示不包含邊界 1900..1999           //20世紀包含邊界 2000..<2100        //21世紀(不包含邊界) 'A'..'D'                 //A,B,C,D 10..1                    //10,9,....,1 'Z'.. 'X'                // Z,Y和X

範圍可以根據下标通路 def reversedTen = 10..1 reversedTen[2]                          //8

這個例子表示範圍的升序降序可以通過整型表達式表示: def start = 10 def finish = 20 start..finish + 1         //[10~21]

範圍的方法: contains:如果目前範圍包含元素則傳回true get:傳回目前範圍中給定位置的元素 getFrom/getTo:擷取目前範圍中下标最大最小的元素 isReverse:目前範圍是否為逆序 size: subList:取之間的值,不包含toIndex

1.定義一個方法 Groovy中定義一個方法關鍵字還是def def greetings(){     print "Hello and welcome" } greetings()

2.在一行中使用多個語句用分号分開 def greetings(){     print "Hello e"; print "and welcome" } greetings()

3.方法參數 Groovy是弱類型語言,是以方法簽名中的參數沒有類型,隻有名稱 def greetings(name){     print "Hello e"; print "and welcome ${name}" } greetings("John")

多個參數用逗号分隔,可以有預設值, def someMethod(para1,para2 = 0,para3 = 0 ){ }

4.方法傳回值 在方法簽名上沒有展現,在方法體重直接用retrun傳回就可以了

5.隐式傳回值 其實 就是return語句是可以不寫的,最後一句語句的值就是傳回值

6.參數傳遞 Groovy沒有引用傳遞和值傳遞之分,隻有傳值方式,也就是java的值傳遞。 也就是說在方法内部修改變量,外側的變量不受影響。 集合(清單、映射、範圍也可以作為方法的參數和傳回值)

7.作用域 在方法内定義的變量,隻能在方法内使用,方法外部不能通路。 另外Groovy入門經典這本書說,在方法内部不能通路方法外的變量,但是,在Groovy2.4.3環境下親測是可以通路的。大概老版本不能通路吧。

8.斷言 跟java一樣也是assert()方法,比如 assert('1'=='1')   如果斷言為真,不輸出任何結果,如果斷言為假則抛出一個異常 類似這樣

|           false

 at test.run(test.groovy:6)

8.while語句 直到括号裡面的值為false時終止循環 def LIMIT =10 def count =1 println 'Start' while(count <=LIMIT){     println "count:${count}"     count++ } println 'Done'

9.for語句 Groovy的for語句隻能使用in關鍵字,in前面是值,in後面可以是清單、映射、範圍、字元串 def LIMIT =10

println 'Start' for(count in 1..LIMIT){     println "count:${count}"     count++ } println 'Done' 以上的意思就是從1開始循環到10,确實代碼量變少,功能更清晰了。

10.if語句  Groovy的if語句和javaScript,java一模一樣

11.switch語句 也和 javaScript,java一模一樣,隻是case中可以是清單、映射、範圍、字元串,正規表達式 當然清單的時候隻要一個符合就可以,字元串要整句比對上才可以。

12.break和continue語句  與java沒有差別

簡而言之,Groovy閉包就是将方法定義成變量。

入門經典對Groovy的閉包定義的很清晰且深入淺出,原文摘錄如下 Groovy閉包是以後總表示可執行代碼塊的方法。閉包也是對象,可以像方法一樣傳遞參數。由于閉包是代碼塊,是以也可以在需要時執行。像方法一樣,在定義的過程中,閉包可以使用一個或者多個參數。閉包的一個重要的特有屬性就是,它們可以通路屬性資訊。這就意味着在聲明閉包之後,閉包可以使用并修改其作用域内的所有變量值。

閉包最常用的用途是處理集合,比如可以周遊沒然後将閉包應用到每個元素上,閉包是Groovy能簡化腳本開發的一個重要原因。

閉包及其調用方法(call是可以省略的) def clos = {param -> println "Heool ${param}"} clos.call('word'); clos('again')

param ->也是可以省略的,稱為隐參數用it代替,顯然隻有一個參數的時候才能這樣 def greeting = 'Hello' def clos = { println "${greeting} ${it}"} clos.call('word') greeting = 'Welcome' clos.call('word')

通過閉包改變方法外屬性值 def greeting = 'Hello' def clos = {param -> println "${greeting} ${param}"} clos.call('word') greeting = 'Welcome' clos.call('word')

輸出是 Hello word Welcome word 這裡做了個是實驗,江閉包放到最後,發現報錯了,可見閉包跟javascript的對象話的方法不一樣,javascript的方法對象,總是首先被讀入記憶體的。

将閉包作為方法參數 def greeting = 'Hello' def clos = {param -> println "${greeting} ${param}"} clos.call('word')

greeting = 'Welcome' clos.call('word')

def demo(clo){     def greeting ='bonjour'     clo.call('Ken') }

demo(clos)

如果方法調用的最後一個參數是閉包,可以把閉包寫到括号後面、 demo(clos) demo()  clos def greeting = 'Hello' def clos = {param -> println "${greeting} ${param}"}

def demo(clo){     def greeting ='Bonjour'     clo.call('Ken') }

//demo()clos demo(){param -> println "Welcom ${param}"} demo clos demo {param -> println "Welcom ${param}"}

最後兩句代碼調用demo方法并江必報作為實參,倒數第二句代碼調用閉包對象,倒數第一句代碼調用 閉包自面值,這兩種方法都省略了方法的括号

注釋掉那句代碼運作時報錯,對比一下後一句,可以看出當有括号時,隻能使用閉包自面值,不能調用閉包對象。

使用閉包求階乘 def factorial = 1 1.upto(2){num -> factorial *= num} println "Factorial(5):${factorial}" println "${1.upto(5){}}"

結果是 Factorial(5):120 null

這裡每次調用 upto方法時都從字面值1開始,一直循環到給定參數5後面的閉包也就執行了五次

閉包用在集合和字元串上 [1,2,3,4].each{print it} 列印結果是 1234 Result: [1, 2, 3, 4]

Groovy有很多方法是利用閉包的,我就不一一寫了。

舉個栗子 class Account{     def number     def balance         def credit(amount){         balance += amount     }         def debit(amount){         if(balance >= amount)             balance = amount     }         def display(){         println "Account ${number} with balance ${balance}"     } }

def acc = new Account(number:'ABC123',balance:1200) acc.display() acc.credit(200) acc.display()

輸出是:

Account ABC123 with balance 1200 Account ABC123 with balance 1400

除了初始化類的方式之外,和java文法貌似沒有什麼不同。可以想象實作方式一定是java的getter和setter方法。

構造器 Groovy中也可以顯式的聲明構造方法,用來初始化類的屬性。 構造器和方法的最大差別在與構造器名和類名相同。 class Account{     def number     def balance         def Account(number ,balance){         this.number = number         this.balance = balance     }         def credit(amount){         balance += amount     }         def debit(amount){         if(balance >= amount)             balance = amount     }         def display(){         println "Account ${number} with balance ${balance}"     } }

//def acc = new Account(number:'ABC123',balance:1200) def acc = new Account('ABC123',1200) acc.display() acc.credit(200) acc.display()

這樣一來Groovy的類同java的類就非常像了。

繼續閱讀