Immer wenn ich Werte in einem Array austausche, stelle ich sicher, dass ich einen der Werte in einer Referenzvariablen gespeichert habe. Ich habe jedoch festgestellt, dass Ruby zwei Werte zurückgeben und automatisch zwei Werte austauschen kann. Beispielsweise,
array = [1, 3, 5 , 6 ,7]
array[0], array[1] = array[1] , array[0] #=> [3, 1]
Ich habe mich gefragt, wie Ruby das macht.
Antworten:
Im Gegensatz zu anderen Sprachen ist der Rückgabewert eines Methodenaufrufs in Ruby immer ein Objekt. Dies ist möglich, weil es wie alles in Ruby
nil
selbst ein Objekt ist.Es gibt drei Grundmuster, die Sie sehen werden. Keinen bestimmten Wert zurückgeben:
Rückgabe eines singulären Wertes:
Dies entspricht den Erwartungen anderer Programmiersprachen.
Beim Umgang mit mehreren Rückgabewerten sieht es etwas anders aus. Diese müssen explizit angegeben werden:
Wenn Sie einen Aufruf tätigen, der mehrere Werte zurückgibt, können Sie diese in unabhängige Variablen aufteilen:
Diese Strategie funktioniert auch für die Art der Substitution, von der Sie sprechen:
quelle
[1, 2]
und dies funktioniert genauso wie in den obigen Beispielen.1,2
an sich ungültig ist, aber entweder vonreturn 1,2
oder[1,2]
funktioniert.Nein, Ruby unterstützt die Rückgabe von zwei Objekten nicht. (Übrigens: Sie geben Objekte zurück, keine Variablen. Genauer gesagt, Sie geben Zeiger auf Objekte zurück.)
Es unterstützt jedoch die parallele Zuweisung. Wenn Sie mehr als ein Objekt auf der rechten Seite einer Aufgabe haben, werden die Objekte in einem
Array
:Wenn Sie mehr als ein "Ziel" (Variablen- oder Setter-Methode) auf der linken Seite einer Zuweisung haben, werden die Variablen an Elemente eines
Array
auf der rechten Seite gebunden :Wenn die rechte Seite ist nicht ein
Array
, wird es zu einem mit dem umgewandeltento_ary
VerfahrenUnd wenn wir die beiden zusammenfügen, bekommen wir das
Damit verbunden ist der Splat-Operator auf der linken Seite einer Zuweisung. Es bedeutet "nimm alle übrig gebliebenen Elemente von
Array
auf der rechten Seite":Und zu guter Letzt können parallele Zuweisungen in Klammern verschachtelt werden:
Wenn Sie
return
von einer Methode odernext
oderbreak
aus einem Block, wird Ruby - dieses Art-of wie die rechte Seite einer Zuweisung behandeln, soDies funktioniert übrigens auch in Parameterlisten von Methoden und Blöcken (wobei Methoden strenger und Blöcke weniger streng sind):
Blöcke, die "weniger streng" sind, machen zum Beispiel die
Hash#each
Arbeit aus. Es tatsächlichyield
sa einziges Zwei-ElementArray
von Schlüsseln und Wert in den Block, aber wir in der Regel schreibenanstatt
quelle
tadman und Jörg W Mittag kennen Ruby besser als ich und ihre Antworten sind nicht falsch, aber ich glaube nicht, dass sie antworten, was OP wissen wollte. Ich denke, dass die Frage nicht klar war. Nach meinem Verständnis hat das, was OP fragen wollte, nichts mit der Rückgabe mehrerer Werte zu tun.
Die eigentliche Frage ist, wenn Sie die Werte von zwei Variablen
a
undb
(oder zwei Positionen in einem Array wie in der ursprünglichen Frage) ändern möchten , warum es nicht erforderlich ist, eine zeitliche Variabletemp
wie die folgende zu verwenden:kann aber direkt gemacht werden wie:
Die Antwort ist, dass bei Mehrfachzuweisungen die gesamte rechte Seite vor der Zuweisung der gesamten linken Seite ausgewertet wird und nicht einzeln ausgeführt wird. Ist
a, b = b, a
also nicht gleichbedeutend mita = b; b = a
.Die erste Bewertung der gesamten rechten Seite vor der Zuweisung ist eine Notwendigkeit, die sich aus der Anpassung ergibt, wenn beide Seiten
=
unterschiedliche Anzahlen von Begriffen haben, und die Beschreibung von Jörg W Mittag kann indirekt damit zusammenhängen, aber das ist nicht das Hauptproblem.quelle
Arrays sind eine gute Option, wenn Sie nur wenige Werte haben. Wenn Sie mehrere Rückgabewerte wünschen, ohne die Reihenfolge der Ergebnisse kennen zu müssen (und durch diese verwirrt zu sein), besteht eine Alternative darin, einen Hash zurückzugeben, der die gewünschten benannten Werte enthält.
z.B
quelle