Groovy:隐式调用不适用于闭包内的实例变量

标签 groovy closures

类实现了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/

相关文章:

java - 当我在 groovy 中使用正则表达式替换时,如何解决 java.lang.StackOverflowError 问题?

groovy - 如何确定NodeChild中给定属性的命名空间

java - Gradle:验证类列表在构建时的类路径中

javascript - 如何在列表函数中修复此闭包?

groovy - 如何从Groovy文件解析多个类

Groovy 构造函数

javascript - 函数 js 中的函数

go - 将 context.Context 传递给在单独的 goroutine 中执行的闭包的最佳方法

scala - "Closures"是如何如此强大的抽象,以至于使用它来实现对象系统和基本控制结构?

javascript - 闭包对象的继承和方法的重写