Groovy:隐式调用不在闭包内的实例变量上工作

时间:2014-03-01 17:25:28

标签: groovy closures

类实现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()

1 个答案:

答案 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()