2012-03-23 91 views
0
a = Array.new(3,[]) 
a[1][0] = 5 
a => [[5], [5], [5]] 

我認爲這沒有道理! 是不是應該a => [[],[5],[]] 或者這是Ruby的特性?更改數組數組中的一個數組會更改它們;爲什麼?

+0

另請參閱http://stackoverflow.com/questions/4642395/in-ruby-why-does-array-newsize-object-create-an-array-consisting-of-multiple和http:// stackoverflow。 com/questions/4601652/ruby​​-array-creation-array-new-vs/4601727#4601727 – Phrogz 2012-03-23 06:35:24

回答

4

使用這個代替:

a = Array.new(3){ [] } 

與您的代碼相同的對象用於每個條目的值;一旦你改變其中一個引用,你會看到所有其他引用的變化。使用上面的代碼,每次需要新值時調用該塊,每次返回一個新的數組


這在本質上爲什麼下面沒有按預期工作新用戶的問題類似:

str.gsub /(<([a-z]+)>/, "-->#{$1}<--" 

在上面,串插發生gsub方法之前是有史以來叫,所以它不能在你的字符串中使用當時的$1值。同樣,在你的問題中,你創建一個對象,並在之前將它傳遞給Array.newRuby開始創建數組插槽。是的,運行時可能默認情況下調用dup項目...但這可能是災難性的和緩慢的。因此,您可以通過塊表單自行確定如何創建初始值。

+2

輕微挑剔:「一旦你改變了其中一個實例你將它們全部變異」 - 實際上,只有*一個*實例,這就是正是這個問題! – 2012-03-23 09:42:13

+0

這是不好的措辭;謝謝。我改變了它。 – Phrogz 2012-03-23 12:54:43