4

我有一个关于使用数组insert的问题。delete_at如果我将一个元素插入到数组 ( arry) 中,然后将该值存储在不同的变量 ( temp) 中,为什么temp在我使用delete_aton后变量会发生变化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]
4

3 回答 3

6

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

temp = arry.dup
于 2013-06-16T21:52:24.753 回答
1

我只是感觉心情不错,可以比以前的评论者说更多的东西,因为前段时间我对所有这些按值传递引用的东西几乎同样头痛。所以:

Ruby 的变量实际上是对 Ruby 虚拟机中的底层对象的引用。它们被“按值”传递给函数,这意味着当你这样做时function(arg)function实际上会获得对内存对象的引用副本。因此,function获取对对象的有效引用,arg以及引用的副本arg。当您对引用的对象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 你的数组,因为以前的评论者给了你全面的实用答案。

于 2013-06-17T00:07:16.720 回答
1

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

temp = arry.dup
于 2013-06-16T21:53:22.270 回答