2010-03-02 9 views
19

Kod wewnątrz zamknięć może odnosić się do zmiennej it.Zamknięcia zagnieżdżone Groovy z użyciem "go"

8.times { println it } 

lub

def mywith(Closure closure) { 
    closure() 
} 

mywith { println it } 

Z tego zachowania w pamięci nie można oczekiwać, aby wydrukować następujący kod 0011

2.times { 
    println it 

    mywith { 
     println it 
    } 
} 

I zamiast muszę napisać

2.times { i -> 
    println i 

    mywith { 
     println i 
    } 
} 

Moje pytanie brzmi: dlaczego zamknięcia bez parametrów zastępują zmienną it, nawet jeśli nie są potrzebne.

Odpowiedz

13

myślę, że to ma coś wspólnego z formal Closure definition z Groovy:

Zamknięcia może mieć 1 ... n argumenty, , które mogą być wpisane statycznie lub bez typu. Pierwszy parametr to dostępny przez niejawny niepodany identyfikator , który nazwał go, jeśli nie podano jawnych argumentów . Jeśli wywołujący nie określi żadnych argumentów, pierwszy parametr (i, odpowiednio, ) będzie miał wartość null.

Oznacza to, że Groovy Zamknięcie zawsze mają co najmniej jeden argument, zwany to (jeśli nie podano inaczej) i to będzie null, jeśli nie podano jako parametr.

Drugi przykład wykorzystuje zamiast tego zasięg zamkniętego zamknięcia.

+0

Dzięki za formalną definicję –

19

Jeśli zdefiniujemy zamknięcie jak ten

def closure = {println "i am a closure"} 

wydaje się mieć żadnych parametrów, ale w rzeczywistości ma ona jeden parametr o nazwie it niejawny. Potwierdza to:

def closure = {println "i am a closure with arg $it"} 
closure("foo") 

która drukuje

"Jestem zamknięcie z arg foo"

Jeśli naprawdę chcesz zdefiniować zamknięcie, które odbywają 0 parametry, użyj tego :

def closure = {-> println "i am a closure"} 

Twój przykład może zostać przepisany jako:

2.times { 
    println it 

    mywith {-> 
     println it 
    } 
} 
+0

Dzięki. Jawne zamknięcie zerowego parametru nie będzie ładnie wyglądać w mini-DSL. –

+0

Wierzę, że w tym przypadku zmienną 'it', która zostanie wydrukowana w zamknięciu' mywith' jest zmienna wolna (http://groovy.codehaus.org/Closures#Closures-Freevariables). – TheAmpersand

Powiązane problemy