为什么Hash值会在Ruby中受到影响

时间:2013-07-02 09:43:52

标签: ruby hash

mainhash = { 'A' => [ 0,1,2,3,4  ]  , 'B' => [ 0 ,1,2 ,3 ]  } 

ahash = mainhash['A']

indval = ahash.shift  

ahash变为如下

[1, 2, 3, 4]

mainhash变为如下

{"A"=>[1, 2, 3, 4], "B"=>[0, 1, 2, 3]}    

我通过从ahash移位一些值来操纵ahash变量。当我执行此操作时,它会影响mainhash值。为什么会这样?

我是否缺少任何概念性理解?

3 个答案:

答案 0 :(得分:3)

Array#shift

  

删除self的第一个元素并将其返回(将所有其他元素向下移动一个)。如果数组为空,则返回nil。

mainhash = { 'A' => [ 0,1,2,3,4  ]  , 'B' => [ 0 ,1,2 ,3 ]  } 

ahash = mainhash['A']
p ahash.object_id # => 8577888
p mainhash['A'].object_id # => 8577888
p indval = ahash.shift # => 0

如上所述,ahashmainhash['A']引用相同的数组对象[ 0,1,2,3,4],因此更改ahash#shift会导致0从{{1}中移除这也会导致ahash0中删除。

说你的 Hash 如下:

mainhash['A']

所有操作都是合法的,并且正如我在上面给出的链接所记录的那样。

  

如何避免影响mainhash

正如@Marek Lipka所说:

你应该使用dup方法:ahash = mainhash [' A']。dup

mainhash
# => {"A"=>[1, 2, 3, 4], "B"=>[0, 1, 2, 3]}

答案 1 :(得分:3)

这是因为ahashmainhash都引用了同一个Array实例。如果你通过ahash修改它,那么引用的对象正在被修改,所以难怪它也会在mainhash中发生变化。

要对对象而不是同一对象进行复制(准确的浅拷贝)操作,应使用dup方法:

ahash = mainhash['A'].dup

答案 2 :(得分:0)

  

为什么会这样?

arr = [1, 2, 3]
x = arr

arr.shift

p arr
p x

--output:--
[2, 3]
[2, 3]

arr和x都指向同一个数组。分配('=')不会创建副本。

现在看看这段代码:

arr = [1, 2, 3]
x = arr.dup

arr.shift
p arr
p x

--output:--
[2, 3]
[1, 2, 3]

顺便说一下,名字'ahash'是一个可怕的数组名称。