我想知道将闭包对象传递给方法的真正用途是什么。
假设我有一个关闭:
def a = {
println it
}
(考虑它正在进行某种操作而不仅仅是打印)
现在我只是将这个闭包a
传递给方法:
def testMethod(def input,Closure a){
a(input)
}
testMethod "MethodPointer", a //passing closure.
现在问题是为什么间接的这个级别?为什么testMethod
无法直接处理其input
?是的,在这里我要在input
处理a
,但是为什么要这样做呢?传递闭包的真正用途是什么?
提前致谢。
答案 0 :(得分:7)
如何在没有collect
参数的情况下编写Closures
方法?它会比现在复杂得多。对于构建者来说也是如此,inject
,each
,with
还有更多......
它允许您定义通用的东西,然后在以后使其更具体。例如,collect
方法可以描述为“获取集合或可迭代,并为每个元素DO SOMETHING并将其添加到新创建的集合”。如果没有Closures在以后指定此 DO SOMETHING ,collect
的值将是最小的。
慢慢地,你会发现一种更具功能性的思维方式。我可以编写一个函数,而不是编写一个特定的函数来执行特定的任务,而是采用更多适用于多个问题的通用方法,并将每个案例的具体内容放在一个Closure中吗?
例如,请考虑这种程序方法,该方法返回min
和max
之间的数字列表,它们是mult
的倍数:
List<Integer> filter( int min, int max, int mult ) {
List<Integer> multiples = new ArrayList<Integer>() ;
for( int i = min ; i < max ; i++ ) {
if( i % mult == 0 ) {
multiples.add( i ) ;
}
}
multiples
}
println filter( 1, 200, 15 )
如果我们使用Closures(用于过滤)在Groovy中编写它,我们得到:
List<Integer> filter( int min, int max, int mult ) {
(min..max).findAll { it % mult == 0 }
}
println filter( 1, 200, 15 )
(我接受这个例子基本上反映了findAll
的功能,所以可能不是一个很好的例子 - 而且也有些做作)
现在考虑我们想要根据其他一些标准进行过滤(整数存在于数据库中等等)......我们可以先将filter
方法重写为:
List<Integer> filter( int min, int max, Closure<Boolean> filter ) {
(min..max).findAll filter
}
println filter( 1, 200 ) { it % 15 == 0 }
然后,正如您所看到的,我们可以将任何闭包传递给此方法,如果我们想要保留元素,则返回true;如果我们想要删除它,则返回false。
要以命令式的方式执行此操作,您将(可能)最终使用多种方法执行非常类似的任务......
答案 1 :(得分:5)
我们的想法是编写模块化和结构清晰的代码。
我写了一篇关于Closure Design Patterns的博文。您可以使用闭包找到一些模式示例。