groovy - 在 groovy 中查找闭包的自由变量的列表/映射

标签 groovy properties closures free-variable

这是我简单的常规脚本;

def fourtify(String str) {

    def clsr = {
         str*4
    }

    return clsr
}

def c = fourtify("aa")
println("binding variables: ${c.getBinding().getVariables()}")
...

我在这里想做的就是能够使用闭包实例访问自由变量“str”,以更好地了解闭包如何在幕后工作。也许就像 Python 的 locals() 方法。

有办法做到这一点吗?

最佳答案

您定义的闭包不会在 binding 对象中存储任何内容 - 它只是返回作为 str 变量传递的字符串,重复 4 次。

绑定(bind)对象存储未指定类型或使用def关键字定义的所有变量。它是通过 Groovy 元编程功能(更具体地说是 getPropertysetProperty 方法)来完成的。因此,当您定义变量 s 时,例如:

def clsr = {
     s = str*4
     return s
}

然后这个闭包将创建一个带有键s和从表达式str * 4计算的值的绑定(bind)。该绑定(bind)对象只不过是通过 getPropertysetProperty 方法访问的 map 。因此,当 Groovy 执行 s = str * 4 时,它会调用 setProperty('s', str * 4) 因为变量/属性 s 未定义。如果我们做一个稍微简单的更改,例如:

def clsr = {
     def s = str*4 // or String s = str * 4
     return s
}

那么绑定(bind)s将不会被创建,因为setProperty方法不会被执行。

对您的示例的另一条评论。如果你想看到绑定(bind)对象中的任何内容,你需要调用返回的闭包。在上面的示例中,闭包被返回,但它永远不会被调用。如果您这样做:

def c = fourtify("aa")
c.call()
println("binding variables: ${c.getBinding().getVariables()}")

然后你的闭包被调用,绑定(bind)对象将包含绑定(bind)(如果有的话)。现在,如果您将示例修改为如下所示:

def fourtify(String str) {

    def clsr = {
        def n = 4 // it does not get stored as binding
        s = str * n
        return s
    }

    return clsr
}

def c = fourtify("aa")
c.call()
println("binding variables: ${c.getBinding().getVariables()}")

您将看到以下输出:

binding variables: [args:[], s:aaaaaaaa]

希望有帮助。

关于groovy - 在 groovy 中查找闭包的自由变量的列表/映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52839085/

相关文章:

wpf - ViewModel 中的依赖属性有什么例子吗?

java - 如何使用 Java 属性文件?

循环内的 JavaScript 闭包 – 简单的实际示例

javascript - 对理解闭包有一点帮助吗?

xml - Groovy XmlSlurper 访问根节点中的属性值

java - Grails 命名约定

map 中的 Groovy 对象属性

dictionary - 为什么我无法获得与在 Groovy 中映射的完全相同的 GString?

javascript - 如何在java脚本中声明未知大小的用户定义对象数组

javascript - 如何使用闭包在循环中使用 then()