我期待得到:紅寶石#times不返回什麼,我認爲它應該
array # => [[1, 0], [2, 0]]
如果我運行下面的代碼:
array = []
position = [0, 0]
2.times do
position[0] += 1
array << position
end
我得到:
array # => [[2, 0], [2, 0]]
有人能解釋一下這裏發生了什麼嗎?
我期待得到:紅寶石#times不返回什麼,我認爲它應該
array # => [[1, 0], [2, 0]]
如果我運行下面的代碼:
array = []
position = [0, 0]
2.times do
position[0] += 1
array << position
end
我得到:
array # => [[2, 0], [2, 0]]
有人能解釋一下這裏發生了什麼嗎?
position
是一個對象。當您致電array << position
時,您真正在做的是將position
的參考添加到array
。這意味着,無論您何時修改position
,所有對它的引用都將反映這些更改。
要獲得您期待的結果,您可以在每次傳遞過程中製作position
數組的副本。這樣,後續的通行證不會改變你的結果。
array = []
position = [0, 0]
2.times do
position[0] += 1
array << position.clone
end
puts array.inspect
這裏的事情是,位置[0]是第一個等於[0,1]與您的語句:
position[0] += 1
這使得它看起來像你 '鏟'[0, 1],第二次[0,2]。鏟運營商的事情是,它不像=
作業。這與<<
'突變調用者'的概念有關。我覺得它更容易被看到它在行動,明白這一點:
a = "Hello!"
b = a
a << ", my friend"
puts a # a is now "Hello!, my friend"
puts b # b is now "Hello!, my friend"
的<<
運營商不重新分配什麼a
在內存空間指向。此相反的是=
操作,不發生變異來電:
a = "How about this?"
b = a # b is now "How about this?"
a = "Not anymore"
puts b # b is still "How about this?"
puts a # a is now "Now anymore"
使用.clone
法關於另一個好答案是很重要的,因爲它什麼叫做「淺拷貝」,這意味着實例變量該對象被複制,但不是它們引用的對象。這就是爲什麼它適用於這種情況。
希望看到鏟運營商是如何工作的,並且改變它的價值是改變所有它的引用,而不僅僅是一個,並使輸出都在數組中相同。如果這沒有完全意義,請在評論中告訴我。
或者,'2×做;數組<< [position [0] + = 1,* position [1 ..- 1]];結束; array#=> [[1,0],[2,0]]'。 –
如果我將位置設置爲0,然後增加位置。最後的array.inspect會顯示[1,2]。爲什麼不是這樣[2,2]? –
@JosephTimmer紅寶石中的數字和其他「原始」類型是不可變的。這意味着你不能改變內存的狀態。當你增加職位時,你實際上是創建一個全新的號碼並重新分配它的位置。因此,最初放入'''array'''的數字保持不變。 Tonys的回答對可變物體的工作原理有很好的解釋。 –