Je viens d'avoir une petite question concernant les boucles en Ruby. Y a-t-il une différence entre ces deux façons d'itérer à travers une collection?
# way 1
@collection.each do |item|
# do whatever
end
# way 2
for item in @collection
# do whatever
end
Je me demande simplement si ce sont exactement les mêmes ou s'il y a peut-être une différence subtile (peut-être quand @collection
est-elle nulle).
x
reste dans le scénario for est due au fait que (généralement) les mots clés ne créent pas de nouvelles étendues. si , à moins que , commence , pour , tandis que , etc., tous fonctionnent avec la portée actuelle.#each
accepte cependant un bloc. Les blocs ajoutent toujours leur propre étendue au-dessus de l'étendue actuelle. Cela signifie que déclarer une nouvelle variable dans le bloc (donc une nouvelle étendue) ne sera pas accessible de l'extérieur du bloc car cette étendue supplémentaire n'y est pas disponible.Voir " The Evils of the For Loop " pour une bonne explication (il y a une petite différence compte tenu de la portée des variables).
L'utilisation
each
est considérée comme une utilisation plus idiomatique de Ruby.la source
Votre premier exemple,
est plus idiomatique . Alors que Ruby prend en charge les constructions en boucle comme
for
etwhile
, la syntaxe des blocs est généralement préférée.Une autre différence subtile est que toute variable que vous déclarez dans une
for
boucle sera disponible en dehors de la boucle, tandis que celles dans un bloc itérateur sont effectivement privées.la source
while
etuntil
ont en fait des utilisations très concrètes qui ne peuvent pas être remplacées par chacune, comme par exemple la génération de valeurs uniques ou pour les REPL.Un autre différent ..
source: http://paulphilippov.com/articles/enumerable-each-vs-for-loops-in-ruby
pour plus de clarté: http://www.ruby-forum.com/topic/179264#784884
la source
Il semble qu'il n'y ait pas de différence,
for
utilise eneach
dessous.Comme Bayard le dit, chacun est plus idiomatique. Il vous cache davantage et ne nécessite pas de fonctionnalités linguistiques spéciales. Selon le commentaire de Télémaque
for .. in ..
place l'itérateur en dehors de la portée de la boucle, doncfeuilles
a
définies une fois la boucle terminée. Oùeach
pas. C'est une autre raison en faveur de l'utilisationeach
, car la variable temp vit une période plus courte.la source
for
n'utilise pas eneach
dessous. Voir d'autres réponses.Ne jamais l'utiliser
for
peut provoquer des bugs presque introuvables.Ne vous laissez pas berner, il ne s'agit pas de problèmes de code ou de style idiomatiques. L'implémentation de Ruby
for
a un sérieux défaut et ne doit pas être utilisée.Voici un exemple où
for
introduit un bug,Impressions
Utilisation d'
%w{foo bar quz}.each { |n| ... }
impressionsPourquoi?
Dans une
for
boucle, la variablen
est définie une seule fois, puis cette définition est utilisée pour toutes les itérations. Par conséquent, chaque bloc fait référence au mêmen
qui a une valeurquz
au moment où la boucle se termine. Punaise!Dans une
each
boucle, une nouvelle variablen
est définie pour chaque itération, par exemple au-dessus de la variablen
est définie trois fois distinctes. Par conséquent, chaque bloc fait référence à un élément distinctn
avec les valeurs correctes.la source
Pour autant que je sache, l'utilisation de blocs au lieu de structures de contrôle en langage est plus idiomatique.
la source
Je veux juste faire un point spécifique sur la boucle for in dans Ruby. Cela peut sembler une construction similaire à d'autres langages, mais en fait c'est une expression comme toutes les autres constructions en boucle de Ruby. En fait, le for in fonctionne avec des objets Enumerable tout comme chaque itérateur.
La collection passée à for in peut être n'importe quel objet qui a une méthode itérateur pour chaque. Les tableaux et les hachages définissent chaque méthode, et de nombreux autres objets Ruby le font également. La boucle for / in appelle la méthode each de l'objet spécifié. Lorsque cet itérateur fournit des valeurs, la boucle for affecte chaque valeur (ou chaque ensemble de valeurs) à la variable (ou aux variables) spécifiée (s), puis exécute le code dans body.
C'est un exemple stupide, mais illustre le point que la boucle for in fonctionne avec N'IMPORTE QUEL objet qui a une méthode each, tout comme la façon dont chaque itérateur fait:
Et maintenant, chaque itérateur:
Comme vous pouvez le voir, les deux répondent à chaque méthode qui renvoie des valeurs au bloc. Comme tout le monde l'a dit ici, il est certainement préférable d'utiliser chaque itérateur sur la boucle for in. Je voulais juste ramener à la maison le point qu'il n'y a rien de magique dans la boucle for in. Il s'agit d'une expression qui appelle chaque méthode d'une collection, puis la transmet à son bloc de code. Par conséquent, c'est un cas très rare que vous auriez besoin d'utiliser pour dans. Utilisez chaque itérateur presque toujours (avec l'avantage supplémentaire de l'étendue du bloc).
la source
Dans la boucle 'for', la variable locale est toujours en vie après chaque boucle. Dans «chaque» boucle, la variable locale est actualisée après chaque boucle.
la source