为什么在一个数组上插入/删除也会修改另一个?

时间:2013-06-16 21:49:49

标签: ruby arrays insert

我对将insertdelete_at与数组一起使用有疑问。如果我将一个元素插入一个数组(arry),然后将该值存储在另一个变量(temp)中,为什么变量temp在我使用delete_at后发生了变化在arry?有没有办法永久地用插入对象存储数组的值?

以下是一些示例代码:

arry = [0,1,3,4]
# => [0, 1, 3, 4]
arry.insert(1,5)
# => [0, 5, 1, 3, 4]
temp = arry
# => [0, 5, 1, 3, 4]
arry.delete_at(1)
# => 5
temp
# => [0, 1, 3, 4]

3 个答案:

答案 0 :(得分:6)

将数组分配给新变量时,不会复制数组本身,只会设置对该数组的引用。如果要将原始数组保存到新变量,则需要克隆该数组 您可以通过dup完成此操作。

temp = arry.dup

答案 1 :(得分:1)

这是因为您使temp变量指向与arry变量相同的对象。要做你想做的事,你应该复制这个对象:

temp = arry.dup

答案 2 :(得分:1)

我只是觉得心情正常,比以前的评论者更能说出一些东西,因为前段时间我对所有这些传递参考价值的东西几乎都有同样的头痛。所以:

Ruby的变量实际上是对Ruby虚拟机中底层对象的引用。它们通过“值”传递给函数,这意味着当您执行function(arg)时,function实际上将引用的副本复制到内存对象。因此,function获取对象的有效引用,argarg引用的副本。当您对arg或其副本引用的对象执行某些操作时,您成功地直接修改了 该对象。 (但是当您在引用上直接操作时,事情只发生在引用上,因此,函数内部的复制引用甚至可能被删除,这不会影响原始引用或对象。请考虑这一点:

array_ref0 = [1,2,3] # actually, this reference represents array
array_ref1 = array_ref0
def f(arg); arg[0] = 0; end
f(array_ref0)
p array_ref0 # => [0,2,3]
p array_ref1 # => [0,2,3]
array_ref0 = [1,2,3]
p array_ref0 # => [1,2,3]
#but!
p array_ref1 # => [0,2,3]

那是因为说array_ref0 = [1,2,3]你重新分配了对新对象的引用,但是array_ref1仍然引用了旧对象,因为> = 1引用了对它的引用(这里不太谈论GC)

def g(arg); arg = nil; end
g(array_ref0)
p array_ref0 # => [1,2,3], because we only nil-ed copy of array_ref0.

希望稍微清理一下。

我没有告诉你#dup你的阵列因为以前的评论者给你全面的实际答案。