簡體   English   中英

如何獲取在Groovy中調用閉包的類(范圍)?

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

注意事項:

  • 序列4出現在2和3之前,因為在那個時間點沒有調用/調用閉包。
  • 序列1打印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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM