轉載請註明出處: http://my.oschina.net/u/874727/blog/741610android
若有問題能夠加Q: 1025250620閉包
非墨寫的文章有時候是比較亂入的。只是以爲讀者可能會須要這一部分的只是,因此臨時插入。本篇文章主要是爲了鞏固一些Groovy的語法知識,主要參考資料來自於Groovy提供的官方文檔。而這些所謂的高級特性,或許你在如今,未來都未必能用到,甚至登上你的平臺。可是知道這些特性可讓你更加的理解Groovy這門語言,已經相似這門語言所要體現出來的語言範式。app
言歸正傳:函數
1.map類型this
map類型是Groovy很經常使用的類型,甚至咱們在定義咱們DSL的時候也常常用到,好比咱們常常用到的.net
apply plugin:"com.android.application"
apply是Groovy的一個函數,然後面的參數就是一個Map類型的對象。通常map定義對象的方式是:代理
def m = [key:value]
可是若是key是引用的一個變量呢?Groovy有兩種方式:code
def key = "name" def m = ["${key}":"david",age:19] //or def m = [(key):"david",age:19]
2.類成員的引用orm
POGO對象經過Groovy所提供的語義和語法糖能夠輕鬆的定義Property:對象
class MyObject { def getName() { "david" } } obj = new MyObject() assert obj.name == "david"
因爲默認範式obj.propertyName下都會被Groovy的get[PropertyName]方法攔截:
class MyObject { def name = "david" def getName() { "["+this.name+"]" } } obj = new MyObject() assert obj.name == "[david]"
爲了直接獲取對象的屬性避免被Groovy攔截須要在屬性名字前面加入@符號
assert obj.@name == "david"
3.函數引用符號&
Groovy中能夠經過&符號引用對象中的函數名,注意這裏是函數名字,並無說明是函數簽名。
def doSomething(Integer int) { println "perform Integer" } def doSomething(String str) { println "perform String" } def funcObj = this.&doSomething assert funcObj(1) == "perform Integer" assert funcObj("ab") == "perform String"
4.屬性分割符號*
直接看代碼吧:
users = [ new User(name:"david",age:19), null, new User(name:"Lily",age:20) ] assert users.*name == ["david",null,"Lily"]
5.運算符重載——符號"[]"
直接看代碼吧:
class User { long id String name def getAt(int i) { switch (i) { case 0: return id case 1: return name } } def putAt(int i,obj) { switch (i) { case 0: id = obj case 1: name = obj } } } user = new User(id:100,name:"david") assert user[1] == "david" user[0] = 11 assert user.id == 11
6.運算符重載——符號"as"
as操做符須要複寫對象中的asType(Class clazz)方法
class MyObject { def asType(Class clazz) { if (clazz == String) { return "abc"} } } obj = new MyObject() String str = obj as String assert str == "abc" assert str intanceof String
沒有構造器的類,能夠指定爲任意接口類型
class MyObj { def callback() { println "perform callback" } } obj = new MyObj() interface Interface1 { def callback() } interface Interface2 { def callback() } i1 = obj as Interface1 i2 = obj as Interface2 i1.callback() i2.callback()
能夠經過as來將map對象轉化爲具體對象
class Person { def name def age } p = [name:"david",age:19] as Person <=> Person p = [name:"david",age:19]
7.運算符重載——符號"()"
class Person { def call(int x) { x + 100} } p = new Person() assert p(1) == 101
8.Map類型參數的展開
若是你的參數是Map對象,那麼能夠將map中的參數進行展開
def func(Map map) { map.each { println it.key+"->"+it.name } } def m = [name:"david",age:19] assert func(m) == func(name:"david",age:19)
9.class的mixin操做
delegate是Groovy中常見的模式,對於Class也不例外。
class A { def callMethodA() {println "call A"} } class B { def callMethodB() {println "call B"} } A.metaClass.mixin B a = new A() a.callMethodA() a.callMethodB() assert !(a instanceof B)
mixin操做可讓classA 擴展出B中的方法,實際上市產生一個動態代理類。而且若是AB類中存在方法衝突,那麼根據Groovy的調用規則,會先調用B中的方法
10.科裏化閉包
科裏化閉包實際上就是給閉包指定默認參數
def testCurry = {int age,String name->println "$name is $age"} //左側賦值: testCurry.curry(12) assert testCurry("david") == "david is 12" //右側賦值: testCurry.rcurry("lily") assert testCurry(9) == "david is 9" //索引賦值: testCurry.ncurry(0,123) assert testCurry("sanny") == "sanny is 123"