我偶然发现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
这将避免奇怪的脚本绑定并按预期使用委托.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。