2010-03-02 3 views
19

Les fermetures à l'intérieur du code peuvent faire référence à la variable it.Fermetures imbriquées groovy avec l'utilisation de 'it'

8.times { println it } 

ou

def mywith(Closure closure) { 
    closure() 
} 

mywith { println it } 

Avec ce comportement à l'esprit que vous ne pouvez pas attendre code suivant pour imprimer 0011

2.times { 
    println it 

    mywith { 
     println it 
    } 
} 

Et au lieu que je dois écrire

2.times { i -> 
    println i 

    mywith { 
     println i 
    } 
} 

Ma question est: pourquoi les fermetures sans paramètres remplacent la variable it même si elles n'en ont pas besoin.

Répondre

13

Je pense qu'il a quelque chose à voir avec le formal Closure definition de Groovy:

Closures peut avoir 1 ... N arguments, qui peut être statiquement typé ou typées. Le premier paramètre est disponible via un argument implicite non typé nommé si aucun argument explicite n'est nommé. Si l'appelant ne spécifie aucun argument, le premier paramètre (et, par extension, ) sera nul.

Cela signifie qu'une fermeture Groovy aura toujours au moins un argument, appelé il (Sauf indication contraire) et il sera nulle sinon donnée comme paramètre.

Le deuxième exemple utilise à la place la portée de la fermeture de fermeture.

+0

Merci pour la définition formelle –

19

Si vous définissez une fermeture comme celui-ci

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

Il semble avoir aucun paramètre, mais en réalité il a un paramètre implicite nommé it. Ceci est confirmé par:

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

qui imprime

« Je suis une fermeture avec arg foo »

Si vous voulez vraiment définir une fermeture qui prend 0 paramètres, utilisez cette :

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

Votre exemple pourrait donc être réécrit comme:

2.times { 
    println it 

    mywith {-> 
     println it 
    } 
} 
+0

Merci. La fermeture explicite des paramètres zéro ne sera pas belle dans les mini-dsls. –

+0

Donc, je crois que dans ce cas, la variable 'it' qui est imprimée dans la fermeture imbriquée' mywith' est une [variable libre] (http://groovy.codehaus.org/Closures#Closures-Freevariables). – TheAmpersand