クロージャとは
Groovyのクロージャは「コードブロック」やメソッドポインタのようなものです。ひと固まりのコードとして定義され、後になって実行されます。
シンプルな例
def clos = { println "hello! }
println "Executing the closure:"
clos() //"hello!" を出力
上の例で、クロージャが定義されたときではなく、 呼ばれた ときに "hello!" が出力されていることに注意してください。
クロージャは、定義されたスコープ内で変数に「束縛」することもできます:
def localMethod() {
def localVariable = new java.util.Date()
return { println localVariable }
}
def clos = localMethod()
println "Executing the closure:"
clos() //"localVariable" が定義された時点の日時を出力
パラメータ
クロージャのパラメータは、以下のように -> トークンの前に並べられます:
def clos = { a, b -> print a+b }
clos( 5, 7 ) //"12" を出力
クロージャ定義が一個以下のパラメータしかとらない場合、-> トークンは任意で省略可能です。
暗黙の変数
クロージャの内部では、特別な意味を持ついくつかの変数が定義されます:
It
単一の引数をとるクロージャでは、以下のようにパラメータ定義を省略することができます:
def clos = { print it }
clos( "hi there" ) //"hi there" を出力
this, owner, delegate
this : Javaと同じように、this はそのクロージャ定義を含むクラスを指す
owner : そのクロージャを含むオブジェクト (this またはそのクロージャを囲んでいるクロージャ)
delegate : デフォルトでは owner と同じだが変更可能。例: builder や ExpandoMetaClass
例:
class Class1 {
def closure = {
println this.class.name
println delegate.class.name
def nestedClos = {
println owner.class.name
}
nestedClos()
}
}
def clos = new Class1().closure
clos.delegate = this
clos()
/* 下記を出力:
Class1
Script1
Class1$_closure1 */
メソッド引数としてのクロージャ
メソッドの最後のパラメータがクロージャの場合、そのクロージャは以下のようにインラインで定義可能です:
def list = ['a','b','c','d']
def newList = []
list.collect( newList ) {
it.toUpperCase()
}
println newList // ["A", "B", "C", "D"]
上の例で collect メソッドは List と Closure を引数にとります。同じことを次のように書くこともできるでしょう(より冗長になりますが):
def list = ['a','b','c','d']
def newList = []
def clos = { it.toUpperCase() }
list.collect( newList, clos )
assert newList == ["A", "B", "C", "D"]
さらに詳しい情報
Groovyでは java.lang.Object を拡張して、クロージャを引数にとるメソッドを数多く追加しています。クロージャの実用的な利用法については GDK Extensions to Object を参考にしてください。
以下も参照してください:






