我是靠谱客的博主 野性灯泡,最近开发中收集的这篇文章主要介绍Groovy 闭包进阶1. 闭包关键变量2. 闭包委托策略,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

1. 闭包关键变量

闭包自带this,owner和delegate关键字。下面写一段测试代码,分别输出闭包这3个变量的值:

def testClouser = {
    println "testClouser this:" + this
    println "testClouser owner:" + owner
    println "testClouser delegate:" + delegate
}

testClouser.call()

输出结果:

testClouser this:variable.variablestudy@662b4c69
testClouser owner:variable.variablestudy@662b4c69
testClouser delegate:variable.variablestudy@662b4c69

可以看到这3个变量输出的值是一样的。
this:表示闭包定义处的类
owner:表示闭包定义处的类或者对象
delegate:表示任意对象,有一个默认值和owner一致
下面多定义几个闭包,测试不同场景下3个参数所代表的的对象。

class Person {
    def static classClouser = {
        println "testClouser this:" + this
        println "testClouser owner:" + owner
        println "testClouser delegate:" + delegate
    }

    def static say() {
        def classClouser = {
            println "methodTestClouser this:" + this
            println "methodTestClouser owner:" + owner
            println "methodTestClouser delegate:" + delegate
        }
        classClouser.call()
    }
}
Person.classClouser.call()
Person.say()

输出结果:

testClouser this:class variable.Person
testClouser owner:class variable.Person
testClouser delegate:class variable.Person
methodTestClouser this:class variable.Person
methodTestClouser owner:class variable.Person
methodTestClouser delegate:class variable.Person

输出结果指向的是类的字节码,不是具体的对象,是因为我们定义的都是static的闭包。
把代码中的static去掉:

class Person {
    def classClouser = {
        println "testClouser this:" + this
        println "testClouser owner:" + owner
        println "testClouser delegate:" + delegate
    }

    def say() {
        def classClouser = {
            println "methodTestClouser this:" + this
            println "methodTestClouser owner:" + owner
            println "methodTestClouser delegate:" + delegate
        }
        classClouser.call()
    }
}
Person p = new Person()
p.classClouser.call()
p.say()

输出结果:

testClouser this:variable.Person@28f2a10f
testClouser owner:variable.Person@28f2a10f
testClouser delegate:variable.Person@28f2a10f
methodTestClouser this:variable.Person@28f2a10f
methodTestClouser owner:variable.Person@28f2a10f
methodTestClouser delegate:variable.Person@28f2a10f

这时候的输出就指向了Person具体对象。
这表明闭包对象this,owner,delegate默认指向最近的封闭类。
下面在闭包中定义闭包,看看这3个变量的值是否一样。

def nestClouser = {
    def innerClouser = {
        println "innerClouser this:" + this
        println "innerClouser owner:" + owner
        println "innerClouser delegate:" + delegate
    }
    innerClouser.call()
}
nestClouser.call()

输出结果:

innerClouser this:variable.variablestudy@28f2a10f
innerClouser owner:variable.variablestudy$_run_closure2@7205765b
innerClouser delegate:variable.variablestudy$_run_closure2@7205765b

可以看到,this指向了闭包定义处的类,owner和delegate一样,都指向了闭包。
如果在类或方法中定义闭包,this,owner,delegate3个变量的值是一样的。如果在闭包里面嵌套定义了闭包,this与owner和delegate的值就不一样了。this还会指向闭包定义处的类的实例或类本身。owner和delegate会指向最近的闭包对象。
那什么情况下owner和delegate会不同了,在代码中手动修改delegate的值:

class Person {

}
Person p = new Person()

def nestClouser = {
    def innerClouser = {
        println "innerClouser this:" + this
        println "innerClouser owner:" + owner
        println "innerClouser delegate:" + delegate
    }
    innerClouser.delegate = p
    innerClouser.call()
}
nestClouser.call()

输出结果:

innerClouser this:variable.variablestudy@7133da86
innerClouser owner:variable.variablestudy$_run_closure2@20ccf40b
innerClouser delegate:variable.Person@2fb3536e

当认为修改delegate的值时,owner和delegate就会出现不一样的情况。
总结:
在大多数场景下,this,owner和delegate的值都是一样的。
在闭包中定义闭包时,this与owner和delegate的值不一样。
在修改闭包的delegate参数时,owner和delegate的值不一样。
this和owner是不可以修改的,delegate可以做做任意修改。

2. 闭包委托策略

先看一段简单的代码:

class Student {
    String name
    def pretty = {"My name is ${name}"}
    String toString() {
        pretty.call()
    }
}

class Teacher {
    String name
}

def stu = new Student(name : 'Sarash')
def tea = new Teacher(name : 'Teacher')
println stu.toString()

输出结果:

My name is Sarash

把上面代码的pretty闭包的delegate和resolveStrategy修改一下:

class Student {
    String name
    def pretty = {"My name is ${name}"}
    String toString() {
        pretty.call()
    }
}

class Teacher {
    String name
}

def stu = new Student(name : 'Sarash')
def tea = new Teacher(name : 'Teacher')
stu.pretty.delegate = tea
stu.pretty.resolveStrategy = Closure.DELEGATE_FIRST
println stu.toString()

输出结果:

My name is Teacher

从结果可以看出闭包优先从tea查找变量,找到之后进行输出。
如果把Teacher的name改成其他命名,由于我们设置了Closure.DELEGATE_FIRST,它先从委托对象寻找,然后从owner对象寻找,最后在Student找到了name属性,进行输出。如果改成Closure.DELEGATE_ONLY,name在Teacher对象找不到name属性,代码会报错。

最后

以上就是野性灯泡为你收集整理的Groovy 闭包进阶1. 闭包关键变量2. 闭包委托策略的全部内容,希望文章能够帮你解决Groovy 闭包进阶1. 闭包关键变量2. 闭包委托策略所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(39)

评论列表共有 0 条评论

立即
投稿
返回
顶部