类实现了call
方法,以便可以将其对象作为方法进行调用。这适用于大多数情况,但当在作为类的实例变量的对象的闭包内进行调用时则无效。
为了演示这个问题,在下面的代码中我用数字注释了有趣的行。虽然大多数变体都会产生相同的输出,但只有带有注释 5
的行不起作用。它抛出groovy.lang.MissingMethodException:没有方法签名:Client2.instanceVar()适用于参数类型:()值:[]
)
有人可以帮我理解原因吗?这是一个错误吗?
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()
最佳答案
我想这会让事情变得清楚。
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()
。
关于Groovy:隐式调用不适用于闭包内的实例变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22117694/