Groovy:为什么闭包不能访问自身?

Sam*_*ong 2 groovy

我是一个 Groovy 新手。当我运行以下脚本时,Groovy 报告“没有这样的属性:类 *** 的 tailFactorial”。闭包不应该访问局部变量 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()}"
Run Code Online (Sandbox Code Playgroud)

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

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()}"
Run Code Online (Sandbox Code Playgroud)

它运行良好。

我们可以发现,这两段代码唯一的区别是,在第一段中,我们同时声明和定义了闭包,而在第二段中,我们没有定义地声明了闭包。定义在一个单独的行中。

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

cfr*_*ick 5

您无法访问将分配给闭包的变量,因为它在右侧之后出现(或者至少没有捕获 get)。

这就是为什么第二个示例(与 groovy 文档中的代码相同)起作用的原因。变量已经声明,闭包可以通过这个名字来捕获它。(请记住,它不是立即执行的关闭代码 - 在这个确切的时间点tailFactorial将为空)。

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

def factorial(int factorialFor) {
    def tailFactorial = { int number, BigInteger theFactorial = 1 ->
        number == 1 ? theFactorial :
        // XXX
        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()}"
Run Code Online (Sandbox Code Playgroud)