dup 和 clone 都返回不同的对象,但是修改它们会改变原始对象

Posted

技术标签:

【中文标题】dup 和 clone 都返回不同的对象,但是修改它们会改变原始对象【英文标题】:Both dup and clone return different objects, but modifying them alters the original object 【发布时间】:2012-09-12 05:37:34 【问题描述】:

当我打印出哈希值时,我有一个值数组用作订单参考。我想修改数组,使数组值“更漂亮”。我想我只是复制或克隆数组,更改值,原始对象将保持不变。但是(在 irb 中)...

@arr = ['stuff', 'things']
a = @arr.clone
b = @arr.dup

所以,至少 a 和 @arr 是不同的对象:

a.object_id == @arr.object_id
=> false

但现在变得奇怪了

a[0].capitalize!
a
=> ['Stuff', 'things']
@arr
=> ['Stuff', 'things'] ##<-what?
b
=> ['Stuff', 'things']## <-what???

好的...所以修改一个会改变其他的,让我们把它改回来?

a[0] = 'stuff'
a
=> ['stuff', 'things']
@arr
=> ['Stuff', 'things'] ## <- WHAT?????

为了完整性 b[1].capitalize!效果一样,三个数组的第二个位置都大写

那么...大写末尾的爆炸是否使它更加有效?足以穿越到其他物体??我知道这样做的其他方法,但这对我来说似乎非常奇怪。我认为这与“浅拷贝”有关。对最佳方式的建议?

【问题讨论】:

【参考方案1】:

dupclone创建数组的新实例,但不是内容,它不是深拷贝。

见:

array0 = ['stuff', 'things']
array1 = array0.clone
array2 = array0.dup

puts "Array-Ids"
p array0.object_id
p array1.object_id
p array2.object_id

puts "Object ids"
array0.each_with_index|_,i|
  p array0[i].object_id
  p array1[i].object_id
  p array2[i].object_id
  p '--------'

数组中的元素共享同一个object_id——它们是同一个对象。数组具有不同的对象 ID。

当您a[0].capitalize! 时,您修改了一个对象,该对象属于三个不同的数组。

另见

Duplicating a Ruby array of strings Deep copy of arrays in Ruby How to create a deep copy of an object in Ruby?

【讨论】:

啊...我明白了。我还发现知道我需要的是“深拷贝”会极大地帮助我的搜索:-P 谢谢!

以上是关于dup 和 clone 都返回不同的对象,但是修改它们会改变原始对象的主要内容,如果未能解决你的问题,请参考以下文章

ruby中的复制 dup clone

在 Ruby 类上定义哪种方法来为其实例提供 dup / clone?

Ruby dup/clone 递归

Java clone() 和 equals() 检查

实体类clone方法,赋值对象修改属性值时不改动原数据

实体类clone方法,赋值对象修改属性值时不改动原数据