クロージャ
JavaプログラマがGroovyを使うとき、最初にぶつかる壁が「クロージャ」でしょう。クロージャとは、「コードブロックを代入した変数」です。Javaでは、コードブロックはメソッドとして定義しましたが、Groovyでは変数に処理を設定し、実行させることが可能です。これは、
変数 = { ……実行する処理…… }
このような形で記述します。文字通り、{}で記述した処理を変数に代入するのです。例えば、このような具合で使います。
msg = { println "Helo" } msg()
1行目で変数msgに処理が代入され、2行目でmsgに代入された処理が実行され"Hello"と出力されます。非常に単純です。ここでは単にメッセージを表示するだけですが、引数として値を渡すことでさらに汎用的な処理を組み込むことももちろん可能です。
msg = { println "こんにちは、${it}さん!" } msg('太郎')
例えば、これを実行すると、"こんにちは、太郎さん!"と出力されます。クロージャとして変数に設定されたブロックコードでは、渡された引数の値を「it」で取り出すことができます。あるいは、
変数 = { 引数1,引数2,…… -> 実行する処理 }
このような形で引数を指定することも可能です。先ほどの例ならば、次のようにしても同じ働きをします。
msg = {str -> println "こんにちは、${str}さん!" } msg('太郎')
クロージャと繰り返し
このクロージャは、Grooyのいたるところで使われています。例えば、配列です。配列には、全要素を繰り返し処理するメソッドが追加されており、クロージャを利用することで簡単に繰り返し処理が行えるようになっています。例えば、1から100までの合計を計算する方法を考えてみましょう。
total = 0 for(def i = 1;i <= 100;i++){ total += i } println total
Java的に考えるなら、このような書き方が思い浮かぶでしょう。が、これは例えば次のように書くこともできます。
total = 0 (1..100).each { total += it } println total
eachは、クロージャをパラメータとして渡せるメソッドです。ここで処理を渡すことで、1..100のすべての要素に対しtotal += itを実行できるというわけです。こうした「クロージャを利用した繰り返し」には、他にもtimesやupto、stepといったものがあります。
total = 0 n = 1 (100).times { total += n++ } println total
例えば、timesは、整数オブジェクトのメソッドで、その整数の回数だけ実行するものです。クロージャを使うことで、決まった処理を一定回数繰り返すことができます。
クロージャを渡すメソッド
この「クロージャを渡すメソッド」というのは、自分で作ることも可能です。実際に簡単な例をあげましょう。
class Counter { def max = 0; Counter(n){ max = n } def show(func){ (0..max).each{ println func(it) } } } new Counter(10).show { it * it }
Counter
クラスにあるshowは、ゼロからmaxまでの整数すべてに対し、引数で渡されたクロージャの処理を実行し出力します。show { it * it }と呼び出せば、0~10までの数字の二乗を出力していきます。クロージャを使うことで、非常に短い行数で複雑な処理を実現できることが分かってきたのではないでしょうか。