Groovy In Action 笔记 (6) -- Closure的Scope

Groovy中Closure是核心一个语言特性,下面分析一下 Closure中this,owner,delegate不同scope:

this: 指的是定义此闭包的类。

owner:如果此闭包定义在另一个闭包里面,那么owner指的是外部的闭包,其他情况同this。

delegate:默认情况下和owner一致。但是此引用是可以指向其他对象,这样的情况下,其scope为新对象。

/*
this: refers to the instance of the class that the closure was defined in.
owner: is the same as this, unless the closure was defined inside another closure in which case the owner refers to the outer closure.
delegate: is the same as owner. But, it is the only one that can be programmatically changed, and it is the one that makes Groovy closures really powerful.
*
*/

class With_Closure{
    String name
    Closure out_closure = {
        Closure inner_closure = {
                println(this.class.name + " " + owner.class.name + " " + delegate.class.name + " " + name.toString())
        }
        inner_closure()
    }

    def test(){
        [1].each {out_closure(it)}
    }
}

With_Closure with_closure = new With_Closure(name: "Hello")
with_closure.test()

////delegate example
class MyOtherClass {
    String myString = "I am over in here in myOtherClass"
}

class MyClass {
    def closure = {
        println(this.class.name + " " + owner.class.name + " " + delegate.class.name + " " + myString.toString())
    }
}

MyClass myClass = new MyClass()

myClass.closure.delegate = new MyOtherClass()
myClass.closure()


//Closure变量优先级:如果 this,owner,delegate 各自的scope里均有定义某个相同变量, 那么 closure调用优先级 : owner(本地变量永远是最先被调用) > this > delegate, 如:

class PriorityClosure{
    def variable = 10 // this scope

    def outer_closure = {
        def variable = 20 // owner(本地变量永远是最先被调用)
        def inner_closure = {
            //def variable = 20 // owner scope 中无法重复定义 variable
            println(variable + " " + "${this.class.name} ${owner.class.name}")
        }
        inner_closure()
    }
}

class PriorityOutClosure{
    def variable = 0 //delegate最后才会被调用
}


PriorityClosure priorityClosure = new PriorityClosure()
priorityClosure.outer_closure() // still 20,因为 owner > delegate; 注释掉 def variable = 20 后,得到结果10

priorityClosure.outer_closure.delegate = new PriorityOutClosure()
priorityClosure.outer_closure() // still 20,因为 owner > delegate; 注释掉 def variable = 20 后,得到结果10;再注释掉 def variable = 10 以及 上一个priorityClosure.outer_closure(),得到结果0

 

posted @ 2020-10-08 20:29  ZackZhou  阅读(157)  评论(0编辑  收藏  举报