闭包
Groovy 语言中闭包( closure )是一个非常重要的概念,而且深入的理解了闭包对充分用好 Groovy 有很大帮助。对闭包比较书面的一种解释“闭包是可以用作函数参数和方法参数的代码块”。其实 Groovy 的闭包更象是一个“代码块”或者方法指针,代码在某处被定义然后在其后的调用处执行。
现在支持闭包的语言有 Scheme 、 Common Lisp 、 Smalltalk 、 Groovy 、 JavaScript 、 Perl , Ruby 和 Python 。
假如你有个函数用来处理集合的值或者对象集合。可能是在选择的值上执行不同的操作。这
些被选择的值可能是一个数组,那么首先看看闭包是如何处理的。
下面的代码是求 1---n 的和
def sum(n)
{ total =
0
for(int i = 2; i <= n; i += 2)
{ total += i
} total
}
println "Sum of even numbers from 1 to 10 is ${sum(10)}"
sum( ) 方法中,你会遍历所有元素并计算他们的和。
如果你现在要求 1 --- n 的乘积 :
def product(n)
{
Java 笨狗 -----Groovy
prod = 1
for(int i = 2; i <= n; i += 2)
{
prod *= i
}
prod
}
println "Product of even numbers from 1 to 10 is ${product(10)}"
你再一次遍历了所有的元素,然后求的乘积。
如果还想把 1---n 开平方后的结果存入集合中 :
def sqr(n)
{ squared =
[]
for(int i = 2; i <= n; i += 2)
{ squared << i
** 2
} squared
}
println "Squares of even numbers from 1 to 10 is ${sqr(10)}"
上面所有的代码,都是使用 1---n 来执行想要的操作 . 你们觉得上面 3 个方法有什么不同之处?
如果你还想对 1---n 执行其他的操作,还会重复的遍历 。个人认为这不适合极限编程,应该
Groovy 的方式
让我们写一个提取偶数的函数。一旦找出偶数,就立即放进代码块执行,让代码块来简单的
输出这个偶数 :
def pickEven(n,block)
{
for(int i = 2; i <= n; i += 2)
{
block(i)
}}
pickEven(10,{ println it } )
pickEven( ) 迭代所有的值 , 然后把合适的值传递给代码块 ------- 闭包。这个可变的代码块持有
一个对闭包的引用。 正如你传递对象一样,你也可以传递闭包。你不必为代码块命名,它
可以是任何合法变量名。当你调用 pickEven( ) 时你可以像上面一样传递一个代码块。这个
代码块 ({}) 传递给参数 block , 10 被传递给变量 n 。在 Groovy 中。你想传递多少闭包进来都可以。这里要注意的是,如果方法的最后一个参数是闭包,一个简单的语法就像下面这样 ,:
pickEven(10) { println it }
Groovy 中的代码块不像 Java ,它不能单独存在,必须依附于一个方法或赋值给一个命名变
量。
代码块中的 it 是什么?假如你只传递一个参数给代码块,那么这个参数在代码块中就可以
使用 it 来引用。当然你可以自己定义一个变量名来引用这个参数 :
pickEven(10) { evennumber -> println evennumber }
再来看看 pickEven( ) 方法。现在可以方便的用于和的计算 :
total = 0
pickEven(10) { total += it }
println "Sum of even numbers from 1 to 10 is ${total}"
同样可以用于乘积 :
product = 1
pickEven(10) { product *= it }
println "Product of even numbers from 1 to 10 is ${product}"
闭包源于 lambda expressions: “ lambda expression 指定参数和函数映射,就是一个包含若干表
达式和语句的匿名函数 ” 。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。