【Groovy】闭包 Closure ( 闭包的 delegate 代理策略 | OWNER_FIRST | DELEGATE_FIRST | OWNER_ONLY | DELEGATE_ONLY )

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
简介: 【Groovy】闭包 Closure ( 闭包的 delegate 代理策略 | OWNER_FIRST | DELEGATE_FIRST | OWNER_ONLY | DELEGATE_ONLY )

文章目录

一、闭包的代理策略引入

二、闭包的四种代理策略





一、闭包的代理策略引入


分别在 Groovy 脚本 和 Test 类中定义 fun 方法 , 打印不同的内容 ;


在闭包 Closure 中分别调用上述两个方法 ,



代码示例 :


// I. 闭包中执行 Groovy 脚本中的方法
def fun() {
    println "fun"
}
def closure = {
    fun()
}
closure()
// II. 闭包中执行 Test 类中的方法
class Test {
    def fun() {
        println "fun2"
    }
}
// 闭包中不能直接调用 Test 对象中的方法
// 此时可以通过改变闭包代理进行调用
def closure2 = {
    fun()
}
// 设置闭包的代理
closure2.delegate = new Test()
// 执行闭包
closure2()



上述代码执行结果 :

image.png



执行上述代码后 , 两个闭包都执行的是 Groovy 脚本中的 fun 方法 ;


即使 closure2 闭包设置的是 Test 实例对象作为代理 , 其仍然执行的是 Groovy 脚本中的 fun 方法 ;


// 设置闭包的代理
closure2.delegate = new Test()


这是因为 Closure 闭包的 代理策略问题导致的 ;


在 Closure 闭包中 , resolveStrategy 成员配置的是该闭包的代理策略 , 默认的代理策略 OWNER_FIRST , 也就是优先从 owner 中查找方法 ; 此时即使在 delegate 中有 fun 方法 , 也会被 owner 中的 fun 方法覆盖 ;


private int resolveStrategy = OWNER_FIRST;






二、闭包的四种代理策略


闭包的四种代理策略 :


OWNER_FIRST : 所有者中的方法优先 ;

DELEGATE_FIRST : 代理优先策略 , 代理中的方法优先 ;

OWNER_ONLY : 只执行所有者中的方法 ;

DELEGATE_ONLY : 只执行代理中的方法 ;

TO_SELF : 只在自身查找 ;

public abstract class Closure<V> extends GroovyObjectSupport implements Cloneable, Runnable, GroovyCallable<V>, Serializable {


 

/**
     * 设置此resolveStrategy后,闭包将首先尝试将属性引用和方法解析给所有者,
     * 然后是委托(<b>这是默认策略)。
     *
     * For example the following code :
     * <pre>
     * class Test {
     *     def x = 30
     *     def y = 40
     *
     *     def run() {
     *         def data = [ x: 10, y: 20 ]
     *         def cl = { y = x + y }
     *         cl.delegate = data
     *         cl()
     *         println x
     *         println y
     *         println data
     *     }
     * }
     *
     * new Test().run()
     * </pre>
     * will output :
     * <pre>
     * 30
     * 70
     * [x:10, y:20]
     * </pre>
     * 因为在测试类中声明的x和y字段在委托中定义了变量<p> 
     * <i>请注意,总是首先查找局部变量,而与解析策略无关。</i>
     */
    public static final int OWNER_FIRST = 0;
    /**
     * 设置此resolveStrategy后,闭包将首先尝试将属性引用和方法解析为委托,然后解析为所有者。
     *
     * 例如,以下代码:
     * <pre>
     * class Test {
     *     def x = 30
     *     def y = 40
     *
     *     def run() {
     *         def data = [ x: 10, y: 20 ]
     *         def cl = { y = x + y }
     *         cl.delegate = data
     *         cl.resolveStrategy = Closure.DELEGATE_FIRST
     *         cl()
     *         println x
     *         println y
     *         println data
     *     }
     * }
     *
     * new Test().run()
     * </pre>
     * will output :
     * <pre>
     * 30
     * 40
     * [x:10, y:30]
     * </pre>
     * 因为在测试类中声明的x和y字段在委托中定义了变量<p> 
     * <i>请注意,总是首先查找局部变量,而与解析策略无关。</i>
     */
    public static final int DELEGATE_FIRST = 1;
    /**
     * 使用此resolveStrategy集,闭包将只解析所有者的属性引用和方法,而不调用委托。
     * 例如,以下代码:
     *
     * <pre>
     * class Test {
     *     def x = 30
     *     def y = 40
     *
     *     def run() {
     *         def data = [ x: 10, y: 20, z: 30 ]
     *         def cl = { y = x + y + z }
     *         cl.delegate = data
     *         cl.resolveStrategy = Closure.OWNER_ONLY
     *         cl()
     *         println x
     *         println y
     *         println data
     *     }
     * }
     *
     * new Test().run()
     * </pre>
     *
     * 将抛出“No-this-property:z”错误,因为即使在委托中声明了z变量,也不会进行查找<p> 
     * <i>请注意,总是首先查找局部变量,而与解析策略无关</我>
     */
    public static final int OWNER_ONLY = 2;
    /**
     * 使用此resolveStrategy集,闭包将只解析委托的属性引用和方法,并完全绕过所有者。
     * 例如,以下代码:
     *
     * <pre>
     * class Test {
     *     def x = 30
     *     def y = 40
     *     def z = 50
     *
     *     def run() {
     *         def data = [ x: 10, y: 20 ]
     *         def cl = { y = x + y + z }
     *         cl.delegate = data
     *         cl.resolveStrategy = Closure.DELEGATE_ONLY
     *         cl()
     *         println x
     *         println y
     *         println data
     *     }
     * }
     *
     * new Test().run()
     * </pre>
     *
     * 将引发错误,因为即使所有者声明了“z”字段,解析策略也将绕过所有者中的查找<p> 
     * <i>请注意,总是首先查找局部变量,而与解析策略无关</i>
     */
    public static final int DELEGATE_ONLY = 3;
    /**
     * 使用此resolveStrategy集,闭包将解析自身的属性引用,
     * 并执行通常的元类查找过程。
     * 这意味着属性和方法既不能从所有者也不能从委托解析,
     * 只能在闭包对象本身上解析。
     * 这允许开发人员使用闭包本身的ExpandoMetaClass覆盖getProperty。<p>
     * <i>请注意,总是首先查找局部变量,与解析策略无关。</i>
     */
    public static final int TO_SELF = 4;
  private int resolveStrategy = OWNER_FIRST;
}


目录
相关文章
|
3月前
|
编译器 C#
C#中内置的泛型委托Func与Action
C#中内置的泛型委托Func与Action
65 4
【Groovy】闭包 Closure ( 闭包的 delegate 代理策略 | OWNER_FIRST | DELEGATE_FIRST | OWNER_ONLY | DELEGATE_ONLY )
【Groovy】闭包 Closure ( 闭包的 delegate 代理策略 | OWNER_FIRST | DELEGATE_FIRST | OWNER_ONLY | DELEGATE_ONLY )
145 0
【Groovy】闭包 Closure ( 闭包的 delegate 代理策略 | OWNER_FIRST | DELEGATE_FIRST | OWNER_ONLY | DELEGATE_ONLY )
【Groovy】闭包 Closure ( 闭包类 Closure 简介 | this、owner、delegate 成员赋值及源码分析 )
【Groovy】闭包 Closure ( 闭包类 Closure 简介 | this、owner、delegate 成员赋值及源码分析 )
166 0
【Groovy】闭包 Closure ( 闭包类 Closure 简介 | this、owner、delegate 成员赋值及源码分析 )
【错误记录】Groovy 闭包使用报错 ( 闭包中不能直接使用外部对象的方法 | 需要先设置 delegate 代理 )
【错误记录】Groovy 闭包使用报错 ( 闭包中不能直接使用外部对象的方法 | 需要先设置 delegate 代理 )
222 0
【错误记录】Groovy 闭包使用报错 ( 闭包中不能直接使用外部对象的方法 | 需要先设置 delegate 代理 )
【Groovy】闭包 Closure ( 闭包调用 与 call 方法关联 | 接口中定义 call() 方法 | 类中定义 call() 方法 | 代码示例 )
【Groovy】闭包 Closure ( 闭包调用 与 call 方法关联 | 接口中定义 call() 方法 | 类中定义 call() 方法 | 代码示例 )
211 0
【Groovy】闭包 Closure ( 闭包调用 与 call 方法关联 | 接口中定义 call() 方法 | 类中定义 call() 方法 | 代码示例 )
【Groovy】闭包 Closure ( 闭包类 Closure 简介 | this、owner、delegate 成员区别 | 静态闭包变量 | 闭包中定义闭包 )(二)
【Groovy】闭包 Closure ( 闭包类 Closure 简介 | this、owner、delegate 成员区别 | 静态闭包变量 | 闭包中定义闭包 )(二)
161 0
【Groovy】闭包 Closure ( 闭包类 Closure 简介 | this、owner、delegate 成员区别 | 静态闭包变量 | 闭包中定义闭包 )(二)
【Groovy】闭包 Closure ( 闭包类 Closure 简介 | 闭包 parameterTypes 和 maximumNumberOfParameters 成员用法 )
【Groovy】闭包 Closure ( 闭包类 Closure 简介 | 闭包 parameterTypes 和 maximumNumberOfParameters 成员用法 )
116 0
【Groovy】闭包 Closure ( 闭包类 Closure 简介 | 闭包 parameterTypes 和 maximumNumberOfParameters 成员用法 )
【Groovy】闭包 Closure ( 闭包中调用 Groovy 脚本中的方法 | owner 与 delegate 区别 | 闭包中调用对象中的方法 )
【Groovy】闭包 Closure ( 闭包中调用 Groovy 脚本中的方法 | owner 与 delegate 区别 | 闭包中调用对象中的方法 )
203 0
【Groovy】闭包 Closure ( 闭包类 Closure 简介 | this、owner、delegate 成员区别 | 静态闭包变量 | 闭包中定义闭包 )(一)
【Groovy】闭包 Closure ( 闭包类 Closure 简介 | this、owner、delegate 成员区别 | 静态闭包变量 | 闭包中定义闭包 )(一)
168 0
Object C学习笔记16-委托(delegate)
  在.NET中都知道委托(delegate),通俗点的解释就是可以将方法作为一个参数传到另外一个方法中使用。   委托是一种引用方法的类型。一旦为委托分配了方法,委托将与该方法具有完全相同的行为。委托方法的使用可以像其他任何方法一样,具有参数和返回值。
974 0