Groovy:为什么关闭访问本身?

时间:2015-05-19 03:33:38

标签: groovy

我是一个Groovy新手。当我运行以下脚本时,Groovy报告"没有这样的属性:tailFactorial for class ***"。闭包不应该访问局部变量tailFactorial?

def factorial(int factorialFor) {
    def tailFactorial = { int number, BigInteger theFactorial = 1 ->
        number == 1 ? theFactorial :
        tailFactorial.trampoline(number - 1, number * theFactorial)
    }.trampoline()
    tailFactorial(factorialFor)
}
println "factorial of 5 is ${factorial(5)}"
println "Number of bits in the result is ${factorial(5000).bitCount()}"

让我感到困惑的是,如果我将上面的代码更改为以下代码:

def factorial(int factorialFor) {
    def tailFactorial
    tailFactorial = { int number, BigInteger theFactorial = 1 ->
        number == 1 ? theFactorial :
        tailFactorial.trampoline(number - 1, number * theFactorial)
    }.trampoline()
    tailFactorial(factorialFor)
}
println "factorial of 5 is ${factorial(5)}"
println "Number of bits in the result is ${factorial(5000).bitCount()}"

运行良好。

我们可以发现两段代码之间的唯一区别在于,在第一段中我们同时声明和定义闭包,但在第二层中我们声明闭包而没有定义。这个定义是分开的。

怎么会发生这种情况?我正在使用Groovy 2.4.3和Java 7,期待您的帮助。感谢。

1 个答案:

答案 0 :(得分:4)

你无法访问闭包将被分配到的变量,因为它在右侧(或者至少没有被捕获)后弹出

这就是为什么第二个例子(与groovy docs中相同的代码)有效的原因。变量已经声明,闭包可以通过此名称捕获它。 (记住,关闭代码不会立即执行 - 在这个确切的时间点console.log将为空)。

但是因为你只对闭包上的trampoline调用感兴趣,你可以简单地在闭包本身上调用它。 tailFactorialtrampoline的一种方法:

Closure