-2
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 值。为什么会这样?

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

4

3 回答 3

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']引用相同的 Array 对象[ 0,1,2,3,4],从而改变了要从中删除的ahash#shift原因,也导致要从中删除。0ahash0mainhash['A']

说你的哈希变成如下:

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

所有操作都是合法的,并且发生在我上面给出的链接中。

如何避免影响主哈希

正如@Marek Lipka 所说:

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

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

ahash = mainhash['A'].dup
ahash.object_id # => 8577516
mainhash['A'].object_id # => 8577600
indval = ahash.shift # => 0
ahash # => [1, 2, 3, 4]
mainhash['A'] # => [0, 1, 2, 3, 4]
于 2013-07-02T09:45:37.837 回答
3

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

要对对象的副本(准确地说是浅副本)而不是同一对象进行操作,您应该使用dup方法:

ahash = mainhash['A'].dup
于 2013-07-02T09:48:45.053 回答
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' 这个名字对于一个数组来说是一个可怕的名字。

于 2013-07-02T09:58:19.713 回答