[英]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.