web-dev-qa-db-fra.com

Déclaration groovy EachWithIndex

Je suis novice dans groovy et j'ai eu quelques problèmes à comprendre les déclarations each{} et eachwithindex{} dans groovy.

each et eachWithIndex sont-ils réellement des méthodes? Si tel est le cas, quels sont les arguments qu’ils prennent?

Dans la documentation groovy, il y a cet exemple particulier:

def numbers = [ 5, 7, 9, 12 ]
numbers.eachWithIndex{ num, idx -> println "$idx: $num" } //prints each index and number

Eh bien, je vois que numbers est un tableau. Quels sont num et idx dans la déclaration ci-dessus? Que fait l'opérateur ->

Je sais que $idx et $num affichent la valeur, mais comment se fait-il que idx et num sont automatiquement associés à l'index et au contenu du tableau? Quelle est la logique derrière tout ça? S'il vous plaît aider.

27
Vamsi Emani

Ce sont des méthodes simples, mais elles suivent un schéma assez spécifique: elles prennent Closure comme dernier argument. Une fermeture est une fonctionnalité que vous pouvez faire suivre et appeler le cas échéant.

Par exemple, la méthode eachWithIndex pourrait ressembler à ceci (à peu près):

void eachWithIndex(Closure operation) {
    for (int i = 0; this.hasNext(); i++) {
        operation(this.next(), i); // Here closure passed as parameter is being called
    }
}

Cette approche permet de construire des algorithmes génériques (comme l'itération sur les éléments) et de modifier la logique de traitement concrète au moment de l'exécution en transmettant différentes fermetures.

En ce qui concerne les paramètres, comme vous le voyez dans l'exemple ci-dessus, nous appelons la fermeture (operation) avec deux paramètres: l'élément en cours et l'index en cours. Cela signifie que la méthode eachWithIndex s'attend à recevoir non pas n'importe quelle fermeture, mais une fermeture qui accepterait ces deux paramètres. A partir d’une syntaxe prospective, on définit les paramètres lors de la définition de la fermeture de la manière suivante:

{ elem, index ->
    // logic 
}

Donc -> est utilisé pour séparer les arguments de la définition de la fermeture de sa logique. Lorsqu'une fermeture ne prend qu'un seul argument, sa définition de paramètre peut être omise. Le paramètre sera alors accessible dans la portée de la fermeture avec le nom it (nom implicite du premier argument). Par exemple:

[1,2,3].each {
    println it
} 

Cela pourrait être réécrit comme ceci:

[1,2,3].each({ elem ->
    println elem
})

Comme vous le voyez, le langage Groovy ajoute du sucre de syntaxe pour rendre ces constructions plus jolies.

40
Oleg Iavorskyi

each et eachWithIndex, parmi beaucoup d’autres, prennent ce que l’on appelle Closure comme argument. La fermeture est juste un morceau de code Groovy enveloppé dans des accolades {}. Dans le code avec tableau:

def numbers = [ 5, 7, 9, 12 ]
numbers.eachWithIndex{ num, idx -> println "$idx: $num" }

il n'y a qu'un seul argument (fermeture ou plus précisément: fonction), veuillez noter que dans Groovy (), les accolades sont parfois optionnelles. num et idx sont juste un alias optionnel pour les arguments de fermeture (fonction), quand on a besoin d'un seul argument, c'est équivalent (it est le nom implicite du premier argument de fermeture, très pratique):

def numbers = [ 5, 7, 9, 12 ]
numbers.each {println "$it" }

Références:

11