2

这是我的简单 groovy 脚本;

def fourtify(String str) {

    def clsr = {
         str*4
    }

    return clsr
}

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

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

有没有办法做到这一点?

4

2 回答 2

1

在您的示例str中是方法/函数的参数fortify

但是也许下面的例子会让你更好地理解闭包:

def c={ String s,int x-> return s*x }

println( c.getClass().getSuperclass() )     // groovy.lang.Closure
println( c.getMaximumNumberOfParameters() ) // 2
println( c.getParameterTypes() )            // [class java.lang.String, int]

locals()Python 的函数更匹配groovy.lang.Script.getBinding ()

这是一个带有脚本的简单示例:

Script scr = new GroovyShell().parse(''' 
    println this.getBinding().getVariables()  // print "s" and "x"
    z = s*(x+1)                               // declare a new script-level var "z"
    println this.getBinding().getVariables()  // print "s", "x", and "z"
    return s*x 
''')
scr.setBinding( new Binding([
        "s":"ab",
        "x":4
    ]) )
println scr.run() // abababab
println scr.getBinding().getVariables() // print "s", "x", and "z"
于 2018-10-16T16:15:33.090 回答
1

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

此对象存储所有未指定类型或使用关键字binding定义的变量。def它是通过 Groovy 元编程功能(getProperty以及setProperty更具体的方法)完成的。因此,当您定义s如下变量时:

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

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

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

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

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

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

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

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]

希望能帮助到你。

于 2018-10-16T16:06:04.177 回答