Ich hatte gerade eine kurze Frage zu Loops in Ruby. Gibt es einen Unterschied zwischen diesen beiden Arten, eine Sammlung zu durchlaufen?
# way 1
@collection.each do |item|
# do whatever
end
# way 2
for item in @collection
# do whatever
end
Ich frage mich nur, ob diese genau gleich sind oder ob es vielleicht einen subtilen Unterschied gibt (möglicherweise wann @collection
ist null).
x
im for- Szenario verbleibt , liegt in der Tatsache, dass (im Allgemeinen) Schlüsselwörter keine neuen Bereiche erstellen. Wenn , es sei denn , beginnen , für , während usw., arbeiten alle mit dem aktuellen Bereich.#each
akzeptiert jedoch einen Block. Blöcke fügen immer einen eigenen Bereich über dem aktuellen Bereich hinzu. Dies bedeutet, dass das Deklarieren einer neuen Variablen im Block (also eines neuen Bereichs) von außerhalb des Blocks nicht zugänglich ist, da dieser zusätzliche Bereich dort nicht verfügbar ist.Eine gute Erklärung finden Sie unter " Die Übel der For-Schleife " (es gibt einen kleinen Unterschied in Bezug auf das variable Scoping).
Die Verwendung
each
wird als idiomatischere Verwendung von Ruby angesehen.quelle
Dein erstes Beispiel,
ist idiomatischer . Während Ruby Schleifenkonstrukte wie
for
und unterstütztwhile
, wird die Blocksyntax im Allgemeinen bevorzugt.Ein weiterer subtiler Unterschied besteht darin, dass jede Variable, die Sie innerhalb einer
for
Schleife deklarieren , außerhalb der Schleife verfügbar ist, während die Variablen innerhalb eines Iteratorblocks praktisch privat sind.quelle
while
unduntil
haben tatsächlich einige sehr konkrete Verwendungen, die nicht durch jede ersetzt werden können, wie zum Beispiel das Generieren eindeutiger Werte oder für REPLs.Noch eine andere ..
Quelle: http://paulphilippov.com/articles/enumerable-each-vs-for-loops-in-ruby
Für mehr Klarheit: http://www.ruby-forum.com/topic/179264#784884
quelle
Es sieht so aus, als gäbe es keinen Unterschied,
for
verwendeteach
darunter.Wie Bayard sagt, ist jeder idiomatischer. Es verbirgt sich mehr vor Ihnen und erfordert keine speziellen Sprachfunktionen. Per Kommentar von Telemachos
for .. in ..
Setzt den Iterator außerhalb des Bereichs der SchleifeBlätter
a
definiert, nachdem die Schleife beendet ist. Wo wieeach
nicht. Dies ist ein weiterer Grund für die Verwendungeach
, da die temporäre Variable eine kürzere Lebensdauer hat.quelle
for
wird nichteach
darunter verwendet. Siehe andere Antworten.Niemals verwenden, da
for
dies fast unauffindbare Fehler verursachen kann.Lassen Sie sich nicht täuschen, hier geht es nicht um idiomatische Code- oder Stilprobleme. Rubys Implementierung von
for
hat einen schwerwiegenden Fehler und sollte nicht verwendet werden.Hier ist ein Beispiel, in dem
for
ein Fehler eingeführt wird:Druckt
Mit
%w{foo bar quz}.each { |n| ... }
DruckWarum?
In einer
for
Schleife wird die Variablen
einmal definiert und dann wird diese eine Definition für alle Iterationen verwendet. Daher beziehen sich alle Blöcke auf denselben,n
derquz
zum Zeitpunkt des Endes der Schleife einen Wert von hat . Fehler!In einer
each
Schleifen
wird für jede Iteration eine neue Variable definiert, beispielsweise wird die Variable obenn
drei Mal getrennt definiert. Daher bezieht sich jeder Block auf einen separatenn
mit den richtigen Werten.quelle
Soweit ich weiß, ist die Verwendung von Blöcken anstelle von Kontrollstrukturen in der Sprache idiomatischer.
quelle
Ich möchte nur einen bestimmten Punkt über die for in-Schleife in Ruby ansprechen. Es mag wie ein Konstrukt erscheinen, das anderen Sprachen ähnlich ist, aber tatsächlich ist es ein Ausdruck wie jedes andere Schleifenkonstrukt in Ruby. Tatsächlich funktioniert das for in mit Enumerable-Objekten genauso wie jeder Iterator.
Die an for in übergebene Auflistung kann ein beliebiges Objekt sein, das über eine Iteratormethode verfügt. Arrays und Hashes definieren jede Methode, und viele andere Ruby-Objekte auch. Die for / in-Schleife ruft jede Methode des angegebenen Objekts auf. Da dieser Iterator Werte liefert, weist die for-Schleife jeden Wert (oder jeden Wertesatz) der angegebenen Variablen (oder Variablen) zu und führt dann den Code im Hauptteil aus.
Dies ist ein dummes Beispiel, veranschaulicht jedoch den Punkt, an dem die for in-Schleife mit JEDEM Objekt funktioniert, das über jede Methode verfügt, genau wie der jeweilige Iterator:
Und jetzt jeder Iterator:
Wie Sie sehen können, reagieren beide auf jede Methode, die dem Block Werte zurückgibt. Wie alle hier angegeben haben, ist es definitiv vorzuziehen, jeden Iterator gegenüber der for in-Schleife zu verwenden. Ich wollte nur den Punkt nach Hause fahren, dass die for-in-Schleife nichts Magisches ist. Es ist ein Ausdruck, der jede Methode einer Sammlung aufruft und sie dann an ihren Codeblock übergibt. Daher ist es ein sehr seltener Fall, den Sie für in verwenden müssten. Verwenden Sie fast immer jeden Iterator (mit dem zusätzlichen Vorteil des Blockumfangs).
quelle
In der 'for'-Schleife lebt die lokale Variable nach jeder Schleife noch. In jeder Schleife wird die lokale Variable nach jeder Schleife aktualisiert.
quelle