3

我想知道将闭包对象传递给方法的真正用途是什么。

可以说我有一个闭包:

def a = {
        println it
 }

(考虑它正在做某种操作,而不仅仅是打印)

现在我只是将这个闭包传递a给一个方法:

def testMethod(def input,Closure a){
        a(input)
}

testMethod "MethodPointer", a //passing closure.

现在的问题是为什么会有这种级别的间接性?为什么不能testMethod直接处理它input?是的,我在这里要进行input关闭处理a,但是为什么要这样做呢?传递闭包的真正用途是什么?

提前致谢。

4

2 回答 2

7

如果没有参数,您将如何编写collect方法Closures?这将比现在复杂得多。Builders, ,inject等等也是如此...eachwith

它允许您定义一些通用的东西,然后在以后使其更具体。例如,该collect方法可以描述为“获取一个集合或可迭代的,并为每个元素做一些事情并将其添加到新创建的集合中”。如果没有闭包在以后指定此DO SOMETHING,则 的值collect将是最小的。

慢慢地,你会找到一种更实用的思维方式。与其编写一个特定的函数来执行特定的任务,我是否可以编写一个函数,它采用更多适用于多个问题的通才方法,并将每个单独案例的细节放在一个闭包中?


编辑

作为一个例子,考虑这个过程方法,它返回一个介于minmax的倍数之间的数字列表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 )

如果我们使用闭包(用于过滤)在 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。

要以命令式风格执行此操作,您将(可能)最终使用多种方法来完成非常相似的任务......

于 2012-07-30T09:23:30.513 回答
5

这个想法是编写模块化和结构化的清晰代码。

我写了一篇关于闭包设计模式的博文。您可以找到一些使用闭包的模式示例。

于 2012-07-30T09:25:00.550 回答