当哈希是一维与二维时,dup会给出不同的结果

时间:2012-11-19 05:48:37

标签: ruby hash shallow-copy dup

dup是浅层副本,因此在执行此操作时:

h = {one: {a:'a', b: 'b'}}
h_copy = h.dup
h_copy[:one][:b] = 'new b'

现在hh_copy相同:{:one=>{:a=>"a", :b=>"new b"}} 是的,那是对的。

但是当h是一维哈希时:

h = {a:'a', b: 'b'}
h_copy = h.dup
h_copy[:b] = 'new b'
h still is: {a:'a', b: 'b'}
h_copy is {a:'a', b: 'new b'}

为什么?

3 个答案:

答案 0 :(得分:3)

您可以将二维哈希视为某种容器,它包含另一个哈希容器。所以你有 2 容器。

当您在dup上呼叫h时,dup会返回最外层容器的副本,但不会复制任何内部容器,因此这是浅拷贝所做的。现在重复后你有 3 容器:h_copy是你的新第三个容器,:one键只指向h的内部容器

答案 1 :(得分:0)

正如你所说,dup是浅层副本。

您似乎希望h_copyh都引用同一个对象。

然后只需h_copy = h(即没有dup)。

h = {a:'a', b: 'b'}
h_copy = h.dup
h_copy[:b] = 'new b'
h #=> {a:'a', b: 'new b'}

答案 2 :(得分:-1)

因此,经过1小时的头脑风暴......我得出的结论是,在多维哈希中,dup为每个键生成相同的object_id,而每个键又引用哈希,而在单维哈希中,object_ids最初是相似的,但是当我们对对象进行任何更改时,Ruby会将新的object_id分配给散列键..

请查看以下代码

h = { :a => "a", :b => "b" } # => {:a=>"a", :b=>"b"} 
h_clone = h.dup #=> {:a=>"a", :b=>"b"} 
h.object_id #=> 73436330 
h_clone.object_id #=> 73295920 
h[:a].object_id #=> 73436400 
h_clone[:a].object_id #=> 73436400 
h[:b].object_id #=> 73436380 
h_clone[:b].object_id #=> 73436380 
h_clone[:b] = "New B" #=> "New B" 
h_clone[:b].object_id #=> 74385280 
h.object_id #=> 73436330 
h_clone.object_id #=> 73295920 
h[:a].object_id #=> 73436400 
h_clone[:a].object_id #=> 73436400

查看多维数组的以下代码

h = { :one => { :a => "a", :b => "b" } } #=> {:one=>{:a=>"a", :b=>"b"}} 
h_copy = h.dup #=> {:one=>{:a=>"a", :b=>"b"}} 
h_copy.object_id #=> 80410620 
h.object_id #=> 80552610 
h[:one].object_id #=> 80552620 
h_copy[:one].object_id #=> 80552620 
h[:one][:a].object_id #=> 80552740 
h_copy[:one][:a].object_id #=> 80552740 
h[:one][:b].object_id #=> 80552700 
h_copy[:one][:b].object_id #=> 80552700 
h_copy[:one][:b] = "New B" #=> "New B" 
h_copy #=> {:one=>{:a=>"a", :b=>"New B"}} 
h #=> {:one=>{:a=>"a", :b=>"New B"}} 
h.object_id #=> 80552610 
h_copy.object_id #=> 80410620 
h[:one].object_id #=> 80552620 
h_copy[:one].object_id #=> 80552620 
h[:one][:b].object_id #=> 81558770 
h_copy[:one][:b].object_id #=> 81558770