Q: 什么是閉包(Closure)?
A: 我們可以把closure簡單地理解為語句塊,下面讓我們來看一下方法聲明和closure定義的相似點:
方法聲明:def?sayHello(name)?{
????println?name
}
sayHello("山風小子")
closure定義:def?sayHello?=?{?name?->
????println?name
}
sayHello("山風小子")
通過代碼比較,大家看出相似點了吧。
closure比方法更靈活,可以作為參數傳入方法(這點類似于C++中的方法指針),而方法比如本例中的sayHello方法可以通過.&操作符來獲得方法閉包
def?sayHello(name)?{
????println?name
}
def?sayHelloMethodClosure?=?this.&sayHello
sayHelloMethodClosure("山風小子")
def hello(c) {
??? c("Daniel")
}
hello(sayHelloMethodClosure)
所以在Grails中大量的使用clsoure。
Q: ?.是什么
A: ?. 是‘安全引用符’,舉例來說:
在Java中,為了程序的魯棒性(robust),在對一個對象進行操作之前,我們會判斷它是否為null
if?(null?!=?obj)?{
??obj.doSomething();
}
而在Groovy就方便多了,您可以用?.來達到上面的目的
obj?.doSomething()
等價于
obj?==?null???null?:?obj.doSomething()
如果obj為null,則obj?.doSomething()的結果為null,否則就正常執行與Java無異:)
實例:
def?obj?=?null
println?obj?.hello()?//?打印出null
由于obj為null,所以就不執行hello(),即便obj中沒有定義hello這個方法也不會報錯 :)
Q: it是什么?
A: 如果您沒有在Groovy的Closure中定義任何變量,那么Groovy會自動幫您定義一個it變量。
舉例來說:
//?此處的a為自己定義的變量
def?c?=?{?a?->?
????println?a
}
c("Hello,?world")
注意上下兩段代碼的區別,下面的Closure沒有定義任何變量,當要引用傳入的參數時,用it來表示
//?此處的it是Groovy自動幫我們定義的變量
def?c?=?{
????println?it
}
c("Hello,?world")
Q: @Property是什么?
A: 這是以前舊版Groovy的寫法,用來定義成員變量,但由于大家反應它太丑了,所以在Groovy1.0+中已不建議使用,請用def替代它。
Q: 如何定制closure的字符串表示?
A: 定制類的字符串表示一般是通過重寫(override)toString方法來完成的:
class?A?{
????String?toString()?{
????????"I?am?A"
????}
}
def?a?=?new?A()
println?"$a"
但定制closure的字符串表示,則稍微特殊一點,是通過it << "closure的字符串表示",
在Groovy1.1中,"$closure"會將StringWriter的一個實例傳給closure的隱式變量it,并引起closure的執行
如果僅僅是closure()的話,并不會有StringWriter實例傳給closure的隱式變量it
def?c?=?{
????println?"closure?is?executed."
??? // 將這條語句看作toString方法就可以了,注意要使用if (it) {}來判斷一下 :)
??? if (it) {
??????? it?<<?"I?am?a?closure?c"
??? }
}
println?"$c"
結果如下所示,閉包c先被執行,然后才執行println打印出closure的字符串表示
closure?is?executed.
I?am?a?closure?c
Q: 出現在閉包中的owner是什么?A: owner其實就是‘擁有’此閉包的一個對象,舉例來說:
class?A?{
????def?c?=?{
?????????println?"c's?owner:?$owner"
????????if?(it)?{
????????????it?<<?"closure?c"
????????}
????????def?innerC?=?{
????????????println?"innerC's?owner:?$owner"
????????}
????}
????String?toString()?{
????????'class?A'
????}
}
def?a?=?new?A()
def?innerC?=?a.c()
innerC()
運行結果:
c's?owner:?class?A
c's?owner:?class?A
innerC's?owner:?closure?c
Q: 為什么Grails比Rails更適用于企業應用?(摘自《對Grails之誤解》)
A: 原因很多,最顯著的兩個原因就是Spring和Hibernate。到目前為止,有不計其數的組織在采用Spring和HIbernate,他們都有既有的Spring上下文環境,以及已經構造好的Hibernate領域對象等。
在我開始參與Grails項目之前,我就經歷過同樣的情況。我們設計Grails的目的就是為了讓它和這些框架盡可能無縫地整合起來。因此,我們打個比方,你可以把一個用Java編寫的Hibernate領域模型及其對應的配置文件直接扔進Grails應用中,然后就可以使用動態的查詢方法,并且直接使用GORM了。
此外,Grails控制器使用了標準的Servlet API對象(如request、response和session等),因此可以和其它的Servlet一起使用。畢竟,掀起它的蓋頭之后,我們會發現它不過是一個Spring MVC應用。另一方面,Rails幾乎是按照和EJB2一樣的方式設計的(在我發現這點時,怎一個“震驚”二字了得!)。也就是說,你在擴展 ActiveController和ActiveRecord等框架對象時,你也就被綁定在了這套框架上。
在Rails里面根本就不存在領域模型的說法,Rails的模型就是數據庫表。這當然是一件好事了,但在企業內部,同一個領域模型可能會在許多不同的應用中服用,比如說桌面應用和Web應用。在Java里,這實際上是非常成熟完善的,通過把類對象及相應映射文件打包成一個JAR文件即可。
Q: 用Grails開發的Web應用如何進行部署?
A: 執行‘grails war’將Web應用打成war包,然后就可以將應用部署到任何符合J2EE規范的Web服務器上了。
To be continued...
附:
朝花夕拾——Groovy & Grails
posted on 2007-04-28 16:21
山風小子 閱讀(2276)
評論(5) 編輯 收藏 所屬分類:
Groovy & Grails