這是要處理我們稱之爲可變性/不可變性和編程語言中的對象引用。與「紅寶石」和「永恆」一些搜索,「引用」會帶來一些不錯的成績,但基本上
array = ["tubular bell single", "bell", "single", "file"]
數組持有引用到一些Ruby對象,這裏String
實例。 「Ruby字符串」實際上是String類的一個實例。您的數組包含對某些String實例的引用。
sentence = array[0] # Ruby terminal shows "tubular bell single"
# But actually, array[0] is a reference to a Ruby Object
數組[0]是對字符串Object的引用,即。數組[0]就像是一個指向字符串的指針。但是當你在你的Ruby終端中調用array[0]
時,實際上你只是對字符串表示感興趣,而不是對象本身,所以在場景後面的Ruby調用類似array [0] .to_string的東西,這樣你就可以看到字符串,而不僅僅是例如#<Object:0x000000031082b0>
,這是Ruby在終端中寫入對象引用並按Enter鍵時通常顯示的內容。
現在不像其他編程語言(如C),String類沒有任何「下面」,沒有「Character」類。一個String實例不是由其他Ruby對象的引用組成的。
當您調用「句子[0]」時,這基本上意味着您希望句子的第一個字母作爲可以操作的Ruby對象。所以它確實在內存中創建了一個新對象。
所以實際上first_letter = sentence[0]
創建新 String實例,這只是方含「T」
然而,當你調用句子[0] =「T」,您呼叫的特定方法的字符串字符串實例,基本上說:用這個替換這封信。當你這樣做時,你正在修改實例本身!
編輯:也許下面將會說清楚。紅寶石使用「對象標識符」,以確定每個對象的實例
a = "Hello World"
b = "Hello again"
c = "Hello World" # Same string representation as a
a.object_id # 26817860
b.object_id # 25401040
c.object_id # 25247200 # Note it's not the same number as a!
array = [a, b, c]
array[0].object_id # 26817860, so it's the instance of a !!
first_letter = a[0] # Ruby shows "H"
first_letter.object_id # 23178100, a different object in memory
現在
a = "A new string"
a.object_id # 24367200, it's again new object in memory
array # ["Hello World", "Hello again", "Hello World"]
array[0].object_id # 26817860, our array[0] still points to the original object_id
但
first_item = array[0] # "Hello World"
first_item.object_id # 26817860 alright, no magic trick, this is still the object_id of "a"
first_item[0] = "X"
first_item.object_id # 26817860 UNCHANGED ! We have really changed our instance and not created a new one !
array # ["Xello World", "Hello again", "Hello World"]
「不過,爲了表示這一點,你需要一個新的字符串實例「 - 這不是造成差異的原因。我通過「像...... to_string'這樣的解釋」,你提到由'p'創建的檢查字符串。這些字符串是在兩種情況中的任何一種情況下新創建的,每次打印時都與這個問題無關。 – sawa
@sawa感謝您指出這一點...現在好點了嗎? –
@CyrilDD當你說「但是當你在你的Ruby終端中調用array [0]」時,會寫一個例子puts(array [0]? – user5415713