groovy 闭包
闭包 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 指定参数和函数映射,就是一个包含若干表 达式和语句的匿名函数 ” 。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |