Groovy 闭包非常酷。要完全理解它们,理解this
、owner
和delegate
的含义非常重要。
this
:指闭包所在类的实例。owner
:通常与this
相同,除非闭包在另一个闭包内部定义,此时owner
指外部闭包。delegate
:与owner
相同,但它是唯一可以通过编程更改的,这使 Groovy 闭包非常强大。
代码示例:
class MyClass {
def outerClosure = {
println this.class.name // 输出 MyClass
println owner.class.name // 输出 MyClass
println delegate.class.name // 输出 MyClass
def nestedClosure = {
println this.class.name // 输出 MyClass
println owner.class.name // 输出 MyClass$_closure1
println delegate.class.name // 输出 MyClass$_closure1
}
nestedClosure()
}
}
def closure = new MyClass().closure
closure()
在上述代码中:
this
值始终指包含类的实例。owner
通常与this
相同,除了嵌套闭包。delegate
默认与owner
相同,可以更改。
闭包不仅仅是匿名函数,它们还能绑定在闭包作用域中未明确定义的变量。例如:
class MyClass {
String myString = "myString1"
def outerClosure = {
println myString; // 输出 myString1
def nestedClosure = {
println myString; // 输出 myString1
}
nestedClosure()
}
}
MyClass myClass = new MyClass()
def closure = new MyClass().outerClosure
closure()
println myClass.myString
如果闭包中未定义变量,会依次检查this
、owner
和delegate
作用域。
还可以通过更改delegate
来改变闭包的行为,如:
class MyOtherClass {
String myString = "I am over in here in myOtherClass"
}
class MyClass {
def closure = {
println myString
}
}
MyClass myClass = new MyClass()
def closure = new MyClass().closure
closure.delegate = new MyOtherClass()
closure() // 输出: "I am over in here in myOtherClass"
每个闭包都有一个resolvedStrategy
属性,可以设置为Closure.OWNER_FIRST
、Closure.DELEGATE_FIRST
、Closure.OWNER_ONLY
、Closure.DELEGATE_ONLY
。
在 Grails 的 GORM 中,delegate
的动态设置有实际应用,例如在Author
类中:
class Author {
String name
static constraints = {
name size: 10..15
}
}
通过闭包和delegate
的设置,实现了更简洁的 DSL 表达约束。
总之,闭包非常强大,可以动态委托给对象,在 Groovy 的元编程能力中起着重要作用,能实现非常有表现力的 DSL。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。