类实现call
方法,以便可以将其对象作为方法调用。这适用于大多数情况,但不是在对象的闭包内进行调用时,该对象是类的实例变量。
为了证明这个问题,在下面的代码中,我用数字评论了有趣的行。虽然大多数变体产生相同的输出,但只有注释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()
答案 0 :(得分: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 = { this.@instanceVar() } //should work now
localVar() // 1
instanceVar() // 2
closure1() // 3
closure2() // 4
closure3() // 5
}
}
new Client().method()
调用closure2()
时,您会看到“Getter Called”。对于在方法内的闭包中访问的全局属性,调用getter。要克服您获得的错误,需要直接访问字段instanceVar
,以隐式使用call()
。