在Ruby中,如何取消链接两个数组?

时间:2015-06-12 02:49:22

标签: arrays ruby

说我有

x=[1,2,3]

我做了 y=x

如果我这样做的话 y.delete_at(0) 然后y变成[2,3]和x,这让我感到惊讶。我想将y等于x,但是无论我对y做什么,都不应该影响x的原始数组。

3 个答案:

答案 0 :(得分:2)

尝试:

y = x.dup

这是赋值运算符在ruby中的工作方式:

x -------------> [1, 2, 3]

x = y

x -------------> [1, 2, 3]
                 ^
                 |
y ---------------+

那是因为x将地址存储在数组[1, 2, 3]所在的内存中。我们说地址是123 Maple Street。当您将x分配给y时,y's值也会123 Maple Street。然后,如果你告诉y拆除其地址中的一间卧室,那么当x看一眼他的地址时,他也会看到一间被拆毁的卧室。

答案 1 :(得分:2)

使用 .dup

> x = [1,2,3]
 => [1, 2, 3] 
> y = x.dup
 => [1, 2, 3] 
> y.delete_at(0)
 => 1 
> y
 => [2, 3] 
> x
 => [1, 2, 3] 

使用 .clone

 > y = x.clone
 => [1, 2, 3] 
 > y.delete_at(0)
 => 1 
 > y
 => [2, 3] 
 > x
 => [1, 2, 3] 

.dup .colne 两者看起来相似,不是吗?

它们都创建了对象的浅表副本(意味着它们不会复制可能在复制的对象中引用的对象)。但是,#clone执行#dup没有的两件事:

  • 复制复制对象的单例类
  • 维护复制对象的冻结状态

未复制单例方法的示例。

使用 .dup

a = Object.new
def a.foo; :foo end
p a.foo
# => :foo
b = a.dup
p b.foo
# => undefined method `foo' for #<Object:0x007f8bc395ff00> (NoMethodError)

现在让我们看看 .clone

a = Object.new
def a.foo; :foo end
p a.foo
# => :foo
b = a.clone
p b.foo
# => :foo

冻结状态:

a = Object.new
a.freeze
p a.frozen?
# => true
b = a.dup
p b.frozen?
# => false
c = a.clone
p c.frozen?
# => true

我希望现在这些东西让你清楚明白了。 :)参考来自coderwall

答案 2 :(得分:-1)

Ruby使用引用。要创建副本,请尝试其中一个

y= x.dup

y= x.clone