加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

为了使groovy闭包修改委托范围中定义的变量,是否需要显式指定del

发布时间:2020-12-14 16:33:07 所属栏目:大数据 来源:网络整理
导读:我偶然发现Groovy关闭和委托的事情,我不确定是该语言的官方部分,甚至可能是一个错误. 基本上我正在定义一个闭包,我从外部源读取一个字符串, 并且类中定义闭包的变量之一需要由闭包修改.我写 一个简单的例子,显示我发现的工作,以及什么不起作用. 如果查看下面
我偶然发现Groovy关闭和委托的事情,我不确定是该语言的官方部分,甚至可能是一个错误.

基本上我正在定义一个闭包,我从外部源读取一个字符串,
并且类中定义闭包的变量之一需要由闭包修改.我写
一个简单的例子,显示我发现的工作,以及什么不起作用.

如果查看下面的测试代码,您将看到一个定义变量的类

animal = "cat"

和动态定义的两个闭包试图修改动物变量.

这工作>

String code = "{ ->   delegate.animal = 'bear';   return name + 'xx' ; }"

但事实并非如此

String code = "{ ->   animal = 'bear';   return name + 'xx' ; }"

似乎我需要使用’delegate’明确限定我的待修改变量.为了这个工作.
(我想我也可以在封闭类中定义一个setter,以便闭包调用以修改值.)

所以….我已经找到了如何使这项工作,但我会感兴趣,如果有人可以指向我一些groovy
doc解释了这背后的规则.

具体来说….为什么简单的任务

animal = 'bear'

影响原始变量?是否有阴影副本在这里制作?

import org.junit.Test

/*
 * Author: cbedford
 * Date: 8/30/12
 * Time: 1:16 PM
 */

class GroovyTest {
    String animal = "cat"
    String name = "fred"

    @Test
    public void testDelegateWithModificationOfDelegateVariable() {
    String code = "{ ->   delegate.animal = 'bear';   return name + 'xx' ; }"
    def shell = new GroovyShell()
    def closure = shell.evaluate(code)

    closure.delegate = this
    def result = closure()

    println "result is $result"
    println "animal is $animal"

    assert animal == 'bear'
    assert result == 'fredxx'
    }


    // This test will FAIL.
    @Test
    public void testDelegateWithFailedModificationOfDelegateVariable() {
    String code = "{ ->   animal = 'bear';   return name + 'xx' ; }"
    def shell = new GroovyShell()
    def closure = shell.evaluate(code)

    closure.delegate = this
    def result = closure()

    println "result is $result"
    println "animal is $animal"

    assert animal == 'bear'
    assert result == 'fredxx'
    }
}

解决方法

Groovy闭包有 five strategies用于解析闭包内的符号:

> OWNER_FIRST:首先检查所有者(定义闭包的位置),然后检查委托
> OWNER_ONLY:检查所有者,仅在明确引用时检查委托
> DELEGATE_FIRST:首先检查委托,然后检查所有者
> DELEGATE_ONLY:首先检查委托,仅在明确引用时检查所有者
> TO_SELF:既未检查委托也未检查所有者

默认值为OWNER_FIRST.由于闭包是动态定义的,因此您的所有者是一个Script对象,它本身具有特殊规则.在Script中编写animal =’bear’实际上会创建一个名为animal的新绑定并为其分配’bear’.

您可以通过简单地更改闭包上的解析策略,然后在调用它之前修复您的测试,而无需显式引用委托:

closure.resolveStrategy = Closure.DELEGATE_FIRST

这将避免奇怪的脚本绑定并按预期使用委托.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读