Groovy学习笔记——闭包的递归调用

如果一个闭包被赋值给一个对象的属性(在脚本中,给一个没有定义过的变量赋值,实际上就是给这个脚本对象添加了一个属性),那么当需要对这个闭包进行递归调用的时候,可以直接使用这个属性的名字进行调用:
// 递归求n!
factorialProperty = { n ->
if (n == 0) return 1
n * factorialProperty(n - 1) // 使用这个属性的名字进行递归调用
}
assert 3628800 == factorialProperty(10)

如果把闭包赋值给一个局部变量,那么就必须先定义这个变量,再进行赋值:
def factorialVar // 先定义
factorialVar = { n -> // 再赋值
if (n == 0) return 1
n * factorialVar(n - 1) // 使用这个局部变量的名字进行递归调用
}
assert 3628800 == factorialVar(10)

但是,如果要在定义局部变量的同时,用闭包初始化这个变量,那么就没有办法使用上面的方法了。这是因为这个闭包先于这个局部变量被定义,所以在这个闭包被定义的时候,在它的上下文中并没有这个局部变量。
在这种情况下,可以通过Closure的[url=http://groovy.codehaus.org/api/groovy/lang/Closure.html#call()]call[/url]方法实现递归调用:
def factorialVar = { n ->
if (n == 0) return 1
n * call(n - 1) // 使用call方法实现递归调用
// n * factorialVar(n - 1) // 错误
}
assert 3628800 == factorialVar(10)

call方法同样可以用于匿名闭包:
assert 3628800 == { n -> n == 0 ? 1 : n * call(n - 1) }(10)

事实上,call方法可以用在任何闭包的递归调用上。

以上代码在Groovy 1.5.7中测试通过。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值