说我有
x=[1,2,3]
我做了
y=x
y.delete_at(0)
然后y变成[2,3]和x,这让我感到惊讶。我想将y等于x,但是无论我对y做什么,都不应该影响x的原始数组。
答案 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