[英]How do I get the class (scope) from which a closure is called in Groovy?
class Box {
Closure click
Box () {
click = {}
}
void onClick() {
click()
}
}
class TextBox extends Box {
List<String> content
TextBox (String[] a) {
super()
content = a
}
}
class Main {
public static void main(String[] args) {
Main m = new Main()
}
Main() {
String[] a = ["Hello world!"]
Box b = new TextBox(a)
b.click = {content.add("You clicked this box!")}
b.onClick() //throws Exception
}
}
(显然,上面是一个简化;实际上,类更多涉及,并且onClick()的调用是由于点击JFrame)
现在,当我尝试运行它(即运行Main.main())时,我得到一个异常:线程“AWT-EventQueue-0”中的异常groovy.lang.MissingPropertyException:没有这样的属性:类的内容:Main
显然,出于某种原因,它是在Main中搜索List,而不是在TextBox或Box中搜索它的位置。 我也试过使用这个,所有者和代表,但他们都指向Main。 我设法让它作为一个参数:
...
void onClick() {
click(this)
}
...
b.click = {it.content.add("You clicked this box!")}
然而,实际上需要将“this”传递给闭包只是因为它能够知道从哪里调用它,这似乎很奇怪。 难道没有更优雅的解决方案吗? 而且,即使确实无法进入TextBox范围,是否有可能进入Box-scope?
请参阅闭包 groovy文档。 注意隐式变量 :this,owner和delegate。
编辑 :在调用之前修复委托:
b.click = {content.add("You clicked this box!")}
b.click.delegate = b
Main() {
String[] a = ["Hello world!"]
Box b = new TextBox(a)
println "1:- $b.click.delegate" //Will print TextBox
b.click = {
println "2:- $b.click.delegate" //Will print Main
//Since the closure is now defined inside Main(),
//Main becomes the delegate. Reset the delegate to TextBox.
b.click.delegate = b
println "3:- $b.click.delegate" //Will print TextBox
content.add("You clicked this box!")
}
println "4:- $b.click.delegate" //Will print Main
b.onClick()
println b.content //Will print [Hello world!, You clicked this box!]
}
//Output:
1:- TextBox@c166770
4:- Main@6dbdc863
2:- Main@6dbdc863
3:- TextBox@c166770
[Hello world!, You clicked this box!]
注意事项:
TextBox
但序列4打印Main
。 请注意, delegate
已经从TextBox
更改(在定义闭包b.click
)到Main
。 为了onClick()
,您可以将onClick()
修改为,而不是在Main
中更改内容
void onClick() {
click.delegate = this
click()
}
有关详细信息,请参阅此脚
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.