2013-02-16 42 views
1
irb(main):009:0> a = "good" 
=> "good" 
irb(main):010:0> a = "good" + "morning" 
=> "goodmorning" 
irb(main):011:0> a = "good" 
=> "good" 
irb(main):012:0> a << " morning" 
=> "good morning" 

直到現在concatenation運營商工作正常。爲什麼「<<」和「+」與凍結字符串對象的行爲不同?

irb(main):013:0> a = "good" 
=> "good" 

irb(main):014:0> a.freeze 
=> "good" 

irb(main):015:0> a.frozen? 
=> true 

irb(main):016:0> a << " welcome" 
RuntimeError: can't modify frozen String 
    from (irb):16 
    from /usr/bin/irb:12:in `<main>' 


irb(main):017:0> a = a + " welcome" 
=> "good welcome" 

但是隨着frozen串差爲IRB<<+並不表現爲他們應該清晰可見。有誰能告訴我這個的原因嗎?

回答

5

他們在做剛好他們應該做的。 <<修改它被調用的字符串,而+更接近str.dup << arg。這種行爲是定義的,記錄在案的標準。

+0

我在講凍結的字符串。你能解釋一下原因嗎? – 2013-02-16 18:19:46

+4

@ user2060534:凍結的字符串與自己創建副本,只是沒有被修改本身,並且淺拷貝不會複製凍結的屬性。 – Linuxios 2013-02-16 18:23:30

1

@Linuxios答案是完美的。

但仍然在這裏我試圖以顯示與更透明的方式修改:

@ubuntu:~$ irb --simple-prompt 
>> a = "good" 
=> "good" 

>> a.freeze 
=> "good" 

>> a.frozen? 
=> true 

>> a.object_id 
=> 10557720 # holds the reference to the "good" string object. 

>> a = a + " morning" 
=> "good morning" 

>> a.object_id 
=> 10415700 # holds the reference to the new string object "good morning". 

>> a.frozen? 
=> false 

>> ObjectSpace._id2ref(10415700) 
=> "good morning" 
>> ObjectSpace._id2ref(10557720) 
=> "good" 
>> ObjectSpace._id2ref(10557720).frozen? 
=> true 

我們可以得出這樣的結論 - 是的,字符串「好」還是凍結。只有發生的事情是a引用新對象「早上好」。只有a的參考分配已更改。

0

<<+對所有字符串對象的行爲不同,不僅僅是凍結的對象。酮(<<)修改一個字符串,而其他(+)返回一個新字符串而不修改原始:

隨着<<

string1 = "good" 
#=> "good" 
string2 = string1 
#=> "good" 
string1 << " morning" 
#=> "good morning" 
string1 
#=> "good morning" 
string2 
#=> "good morning" 

隨着+

string1 = "good" 
#=> "good" 
string2 = string1 
#=> "good" 
string1 = string1 + " morning" 
#=> "good morning" 
string1 
#=> "good morning" 
string2 
#=> "good" 

Object#freeze是特別旨在禁止我以上用<<(它防止對象被修改)展示的那種行爲,所以調用凍結字符串上的會導致錯誤。

相關問題