3

クロージャ オブジェクトをメソッドに渡すことの実際の用途は何なのだろうか。

クロージャーがあるとしましょう:

def a = {
        println it
 }

(単に印刷するのではなく、何らかの操作を行っていると考えてください)

今、私はこのクロージャaをメソッドに渡しています:

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

testMethod "MethodPointer", a //passing closure.

ここで問題は、なぜこのレベルの間接化が行われるのかということです。testMethodを直接処理できないのはなぜinputですか? はい、ここでは Closureinputで処理するようにaしていますが、なぜそうする必要があるのでしょうか? クロージャーを渡すことの実際の用途は何ですか?

前もって感謝します。

4

2 に答える 2

7

パラメータcollectなしでメソッドをどのように記述しますか? Closures現在よりもはるかに複雑になります。ビルダー、injecteachwithその他にも同じことが言えます...

これにより、一般的なものを定義し、後でより具体的にすることができます。たとえば、collectメソッドは「コレクションまたはイテラブルを取得し、各要素に対して何かを実行し、新しく作成されたコレクションに追加する」と記述できます。後日、このDO SOMETHINGを指定する Closures がなければ、 の値はcollect最小限になります。

ゆっくりと、より機能的な考え方に到達します。特定のタスクを実行する特定の関数を作成するのではなく、複数の問題に適用可能な一般的なアプローチを採用する関数を作成し、個々のケースの詳細をクロージャーに入れることはできますか?


編集

例として、 との倍数であるminとの間の数値のリストを返すこの手続き型メソッドを考えてみましょう。maxmult

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 を返す任意のクロージャーをこのメソッドに渡すことができます。

命令型のスタイルでこれを行うには、(おそらく) 非常によく似たタスクを実行する複数のメソッドが必要になります...

于 2012-07-30T09:23:30.513 に答える
5

アイデアは、モジュラーで構造化された明確なコードを書くことです。

Closure Design Patternsに関するブログ投稿を書きました。クロージャーを使用したパターンの例をいくつか見つけることができます。

于 2012-07-30T09:25:00.550 に答える