2010-04-19 16 views
9

Gibt es eine Möglichkeit, anonyme Code-Blöcke in Groovy zu verwenden? Zum Beispiel versuche ich den folgenden Java-Code in Groovy zu übersetzen:Anonyme Code-Blöcke in Groovy

{ 
    int i = 0; 
    System.out.println(i); 
} 
int i = 10; 
System.out.println(i); 

Die nächste Übersetzung ich mit oben kommen kann ist folgendes:

boolean groovyIsLame = true 
if (groovyIsLame) { 
    int i = 0 
    println i 
} 
int i = 10 
println i 

Ich weiß, dass anonyme Code-Blöcke sind oft Art eines Antipatterns. Aber Variablen mit Namen wie "inputStream0" und "inputStream1" zu haben, ist ebenfalls ein Antipattern. Für diesen Code, an dem ich gerade arbeite, wären anonyme Code-Blöcke hilfreich.

+1

Ich weiß nicht, groovy kann so Ihre Frage nicht direkt beantworten, aber warum nicht Ihren Code Refactoring loswerden Ihrer anonymen Codeblöcke? Klingt nach einer besseren Wahl für mich. –

Antwort

14

Sie können anonyme Code-Blöcke in Groovy verwenden, aber die Syntax zwischen diesen und Schließungen ist mehrdeutig. Wenn Sie versuchen, dies zu laufen bekommen Sie tatsächlich diesen Fehler:

Ambiguous expression could be either a parameterless closure expression or an isolated open code block; solution: Add an explicit closure parameter list, e.g. {it -> ...}, or force it to be treated as an open block by giving it a label, e.g. L:{...} at line: 1, column: 1

den Vorschlag folgend, können Sie ein Label verwenden, und es können Sie den anonymen Code-Block verwenden. Umschreiben von Java-Code in Groovy:

l: { 
    int i = 0 
    println i 
} 
int i = 10 
println i 
+2

Nun, es ist kaum "anonym" mehr, wenn du ihm einen Namen gegeben hast, oder? :) –

+0

Danke, das ist ein bisschen sauberer und ersetzt das unnötige "if else" mit einem unnötigen Label. Etwas prägnanter. – piepera

+1

@Michael Wenn das Label zu Anon geändert wurde: dann wird es vielleicht niemand bemerken :) – crowne

1

In Groovy bilden diese Klammern ein Abschluss-Literal. Also, kann nicht tun. Persönlich würde ich in Betracht ziehen, anonyme Sperren für Schließungen ein sehr gutes Geschäft aufgeben zu müssen.

+0

Sie können anonyme Code-Blöcke in Groovy verwenden. Siehe meine Antwort für Details und Beispiel. –

2

Was:

({ 
int i = 0 
println i 
}).() 

int i = 10 
println i 

Ich habe keinen Groovy Installation zur Hand haben, aber das sollte tun.

+0

Ja, das funktioniert gut. Der einzige Nachteil beim Vergleich mit der obigen Lösung von Chris ist, dass der Stack-Trace etwas unordentlicher ist, wenn innerhalb des anonymen Blocks eine Ausnahme auftritt. Aber das ist auch eine gute Lösung, danke! – piepera

+0

Sie können auch die .call() loswerden und ersetzen Sie sie einfach mit() –

+0

Ich bin neugierig, tut '{int i = 0}.()' Funktioniert auch? (Ich meine, ohne die umgebende Klammer? – OscarRyz

5
1.times { 
    // I'm like a block. 
} 
0

Die häufigste Notwendigkeit für einen anonymen Block ist für zusätzliche (möglicherweise Shadowing) Bindungen def verwenden. Eine Option besteht darin, ein Wörterbuchäquivalent für Ihre Bindungen zu erstellen und .with zu verwenden. Am Beispiel in der Frage gegeben:

[i:0].with { 
    println i 
} 

int i = 10 
println i 

Diese Ihr gestylt ein Lisp gibt let Block