本身動手應用Groovy實現Gradle的DSL(二) Groovy的高級特性

轉載請註明出處: 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"
相關文章
相關標籤/搜索