2014-03-01 51 views
2

一個類實現了call方法,以便它的對象可以作爲方法調用。這適用於大多數情況,但不適用於在一個類的實例變量對象的閉包內進行調用的情況。Groovy:隱式調用不在閉包內的實例變量上

爲了演示這個問題,在下面的代碼中,我用數字評論了有趣的幾行。雖然大多數變體都會產生相同的輸出,但只有帶註釋5的行不起作用。它引發groovy.lang.MissingMethodException: No signature of method: Client2.instanceVar() is applicable for argument types:() values: []

有人可以幫我理解原因嗎?這是一個錯誤嗎?

class CallableObject { 
    def call() { println "hello" } 
} 

class Client { 
    def instanceVar = new CallableObject() 

    def method() { 
     def localVar = new CallableObject() 
     def closure1 = { localVar() } 
     def closure2 = { instanceVar.call() } 
     def closure3 = { instanceVar() }  // doesn't work 

     localVar()       // 1 
     instanceVar()      // 2 
     closure1()       // 3 
     closure2()       // 4 
     closure3()       // 5 
    } 
} 


new Client().method() 

回答

1

我想這會說清楚。

class CallableObject { 
    def call() { println "hello" } 
} 

class Client { 
    def instanceVar = new CallableObject() 

    def getInstanceVar() { 
     println "Getter Called" 
     instanceVar 
    } 

    def method() { 
     def localVar = new CallableObject() 
     def closure1 = { localVar() } 
     def closure2 = { instanceVar.call() } 
     def closure3 = { [email protected]() } //should work now 

     localVar()       // 1 
     instanceVar()      // 2 
     closure1()       // 3 
     closure2()       // 4 
     closure3()       // 5 
    } 
} 


new Client().method() 

你會看到 「獲取方法被稱爲」 印刷時調用closure2()。要在方法內的閉包中訪問全局屬性,可以調用getter。爲了克服您遇到的錯誤,需要直接訪問instanceVar字段以隱式使用call()

+0

儘管這會讓DSL的用戶感到意外,但我猜想沒有其他辦法:) – kunal