5

私が抱えている問題を示すコードサンプルを作成しました:

class BindingExample {

    public static void main(String[] args) {

        Closure closure1 = {
            printit.call("Hello from closure 1")
        }

        Closure closure2 = {
            printit("Hello from closure 2")
        }

        Closure printit = { s ->
            println("printing: "+s)
        }

        Binding binding = new Binding()
        binding.setVariable("printit", printit)

        closure1.delegate = binding
        closure2.delegate = binding

        closure1()  //This works fine
        closure2()  //This does not.  

        //Why does .call() work and () alone not?  Most documentation says they're the same.
    }

}

PrintitはClosureドキュメントがdoCallを実装していることを示しているため、()を介して短い形式で呼び出すことができます。

ただし、デリゲートへのバインドを介してこのクロージャが使用可能になると、長い形式の呼び出しのみが許可されます。出力は次のとおりです。

printing: Hello from closure 1
Exception in thread "main" groovy.lang.MissingMethodException: No signature of method: groovy.lang.Binding.printit() is applicable for argument types: (java.lang.String) values: [Hello from closure 2]

誰かがこれが事実である理由を説明できますか?可能であれば、短い形式のバージョンが機能するようにする方法も確認したいと思います。printit適切な静的メソッド(クロージャーではない)として定義することで機能させることができましたが、実際にはメソッドスコープ内でのみ利用可能なデータ(私の質問はバインディング自体に関連しているので、例)。

4

1 に答える 1

2

なぜそうなのかというと、残念ながら明確な答えは出せません。暗黙の「this」アノテーションなどについていくつかの話があります。それは機能するはずですが、最初に何を試すべきか(this-scopeまたはdelegate)についてはあいまいさがあります。

現在、問題が存在することは正しいようです。私は、理由についての解決なしのいくつかの議論とともに、同意する以下の他のリソースを見つけました。

この問題についての簡単な議論:http: //groovy.329449.n5.nabble.com/Binding-Closure-property-not-called-as-method-td5562137.html

結果のJIRAチケット: https ://issues.apache.org/jira/browse/GROOVY-5367

于 2013-03-12T18:04:59.667 に答える