2014-04-18 1 views
6

ich bin in diesem Augenblick durch ein Tutorial zu arbeiten, und ich würde gerne verstehen, warum die folgenden Ereignisse eintritt:Warum hängt `` `an eine Ruby-Zeichenkette, während` + = `nicht?

original_string = "Hello, " 
hi = original_string 
there = "World" 
hi += there 
assert_equal "Hello, ", original_string 

original_string = "Hello, " 
hi = original_string 
there = "World" 
hi << there 
assert_equal "Hello, World", original_string 

Warum += auf original_string keine Wirkung haben, und << tun? Ich war mir absolut sicher, dass der zweite Fall auch gleich "Hello, " sein würde, aber das ist nicht der Fall.

hi = original string in dem ersten Beispiel wird der Wert von original_string in hi zu kopieren, aber hi = original string im zweiten Beispiel hi einzustellen erscheint als original string auf die gleiche Zeichenfolge zu zeigen. Ich denke, es gibt eine Art implizite Entscheidung hinter den Kulissen, ob der Wert kopiert oder die Referenz kopiert werden soll ... oder so.

Antwort

3

<< auf Zeichenfolge mutiert das ursprüngliche Objekt während += eine Kopie erstellt und zurückgibt.

die object_id der jeweiligen Strings Siehe unten:

2.1.1 :029 > original_string = "Hello, " 
=> "Hello, " 
2.1.1 :030 > hi = original_string 
=> "Hello, " 
2.1.1 :031 > there = "World" 
=> "World" 
2.1.1 :032 > original_string.object_id 
=> 70242326713680 
2.1.1 :033 > hi.object_id 
=> 70242326713680 

2.1.1 :034 > hi += there 
=> "Hello, World" 
2.1.1 :035 > hi.object_id 
=> 70242325614780 

Beachten Sie die verschiedenen object_id auf hi auf der Leitung 35. Sobald Sie hi zu original_string in Ihrem Beispiel oben zurückgesetzt, und verwenden Sie <<, ändert es das gleiche Objekt .

3

In beiden Beispielen kopiert hi = original_string die Referenz.

Mit += weisen Sie jedoch hi neu zu, um auf eine neue Zeichenfolge zu zeigen, obwohl der Variablenname derselbe ist.

Dies liegt daran, hi += there erweitert im Interpreter auf den Ausdruck hi = hi + there.

Vor dieser Operation teilen hi und original string einen Verweis auf dasselbe Zeichenfolgenobjekt. Nach der Operation = im erweiterten Ausdruck verweist hi jetzt auf das neu erstellte Zeichenfolgenergebnis hi + there.

In dem Ausdruck hi << there passiert nichts, um zu ändern, auf welches Objekt sich hi bezieht. Es bezieht sich auf die gleiche Zeichenfolge wie original_string, und daher spiegeln sowohl hi als auch original_string die Änderung wider (was natürlich darauf zurückzuführen ist, dass beide auf dasselbe Zeichenfolgenobjekt verweisen).