【发布时间】:2015-07-30 17:33:24
【问题描述】:
我是一个 Groovy 新手。当我运行以下脚本时,Groovy 报告“No such property: 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,期待您的帮助。谢谢。
【问题讨论】:
-
只是因为在您的第一个代码 sn-p 中,
tailFactorial闭包在执行后还不存在,因此无法从其内部访问。 -
Val 是正确的,在第 4 行代码中,您在 tailFactorial 闭包变量的初始化程序中引用了 tailFactorial。由于初始化程序在声明完成之前执行,tailFactorial 变量还不存在,也不能被引用。在第二个例子中,变量是先创建的,没有初始化,所以可以在赋值闭包中引用。
-
@BillJames,我认为闭包声明是可以的,因为初始化执行时不会执行闭包的代码。就像Can't call method itself in grails 说的那样,这是一个技巧。我只是不知道这个技巧是如何工作的。
标签: groovy