我正在使用紅寶石凍結方法。就凍結的定義而言,它凍結了被調用的對象的值。後面我們不能修改那個對象的值。我一定要實現相同的任務,我有一個對象,我執行下面的代碼+ =運算符似乎修改了凍結字符串
a = "Test"
a.freeze
a += "this string"
puts a
這使輸出如下:
Test this string
[Finished in 0.0s]
爲什麼它被修改我的冷凍字符串?
我正在使用紅寶石凍結方法。就凍結的定義而言,它凍結了被調用的對象的值。後面我們不能修改那個對象的值。我一定要實現相同的任務,我有一個對象,我執行下面的代碼+ =運算符似乎修改了凍結字符串
a = "Test"
a.freeze
a += "this string"
puts a
這使輸出如下:
Test this string
[Finished in 0.0s]
爲什麼它被修改我的冷凍字符串?
沒有被修改的冷凍String
與
a += "this string"
這是在內部紅寶石一樣
a = a + "this string"
當您添加您要重新分配a
到一個新的String
在Ruby中有兩個String對象,它將創建一個包含結果的新String(這是的正常行爲運算符支持它的大多數對象)。這使原來的「測試」和「這個字符串」值保持不變。原始的凍結字符串(包含「測試」)將保留在內存中,直到它被垃圾收集爲止。它可以被收集,因爲你已經失去了對它的所有引用。
如果你試圖修改該對象在這種地方:
a << "this string"
,那麼你應該會看到一個錯誤信息RuntimeError: can't modify frozen String
基本上,你搞糊塗a
,局部變量,與String
對象它正指向它。局部變量可以隨時重新分配,與Ruby存儲的對象無關。您可以通過在您的a +=
...行前後檢查a.object_id
來驗證您的情況發生了什麼。
另外值得注意的是:'a.object_id'前後是完全不同的。這是一個有用的診斷,當東西表現*奇怪*,就像一個有克隆元素的數組。 – tadman
的冷凍方法防止你改變對象,它變成一個目的爲恆定。
s1 = "its testing"
s1.freeze
puts "Object ID ===", s1.obejct_id
因此,凍結對象後,嘗試修改它會導致TypeError。
s1 << "testing again"
它會給,RuntimeError:不能修改冷凍字符串
BUT,
凍結一個對象引用操作,而不是在一個可變
s1 += "New Testing"
puts "Object ID ===", s1.obejct_id
將指向評估一個新對象並檢查其對象ID。
有關詳細信息,請參閱本網站, http://rubylearning.com/satishtalim/mutable_and_immutable_objects.html
[凍結在Ruby中的變量不工作]的可能的複製(http://stackoverflow.com/questions/17067171/freezing-variables-in-ruby-不工作) – Manishh
變量有所不同;這就是爲什麼他們被稱爲變量。 –
我看到這是重複的,但這是一個很好的答案,這讓我不願意在它上面使用dup錘。我寧願將[提名的示例](http://stackoverflow.com/questions/17067171/freezing-variables-in-ruby-doesnt-work)標記爲此問題的副本,儘管它比較老 - 它是不是沒有那麼幹淨。 –