0

当我尝试从数组中弹出一个元素时,它会弹出。当我在弹出之前将该数组分配给另一个变量,然后如果我弹出,弹出操作会影响两个数组。

例如:

 ruby-1.9.2-p290 :339 > a= [1,2,3]
     => [1, 2, 3] 
    ruby-1.9.2-p290 :340 > b = a
     => [1, 2, 3] 
    ruby-1.9.2-p290 :341 > a
     => [1, 2, 3] 
    ruby-1.9.2-p290 :342 > b
     => [1, 2, 3] 
    ruby-1.9.2-p290 :343 > a.pop
     => 3 
    ruby-1.9.2-p290 :344 > a
     => [1, 2] 
    ruby-1.9.2-p290 :345 > b
     => [1, 2] #WHY?
    ruby-1.9.2-p290 :346 > x = [1,2,3]
     => [1, 2, 3] 
    ruby-1.9.2-p290 :347 > y = x
     => [1, 2, 3] 
    ruby-1.9.2-p290 :348 > z = x
     => [1, 2, 3] 
    ruby-1.9.2-p290 :349 > y
     => [1, 2, 3] 
    ruby-1.9.2-p290 :350 > z
     => [1, 2, 3] 
    ruby-1.9.2-p290 :351 > y.pop
     => 3 
    ruby-1.9.2-p290 :352 > y
     => [1, 2] 
    ruby-1.9.2-p290 :353 > z
     => [1, 2] # WHY?
    ruby-1.9.2-p290 :354 > x
     => [1, 2] 
    ruby-1.9.2-p290 :355 > 

如果我使用pop,所有变量都会受到影响。如何保留原始数组并仅从另一个数组中弹出?

4

3 回答 3

6

如果将数组分配给新变量,则不会复制它,而只是设置对原始数组的引用。如果要保留原始数组,则必须使用以下方法克隆它dup

ruby-1.9.2-p180 :001 > a = [1,2,3]
 => [1, 2, 3] 
ruby-1.9.2-p180 :002 > b = a.dup
 => [1, 2, 3] 
ruby-1.9.2-p180 :003 > b.pop
 => 3 
ruby-1.9.2-p180 :004 > a
 => [1, 2, 3] 
ruby-1.9.2-p180 :005 > b
 => [1, 2] 
于 2012-05-01T12:05:32.777 回答
3

ruby 中的赋值运算符仅在处理 POD(普通旧数据)对象(如数字、字符串)时才制作值的副本。在其他情况下,它只是将引用复制到对象。

并且不要忘记,那个dup(and clone) 方法只生成对象的浅拷贝。这意味着如果您的数组内部有其他非 POD 对象,它们将不会被复制。

inner = [1,2,3]
 => [1, 2, 3]
outer = [inner, 7,8,9]
 => [[1, 2, 3], 7, 8, 9]

outer_dup = outer.dup
inner.pop
 => 3

outer
 => [[1, 2], 7, 8, 9]
outer_dup
 => [[1, 2], 7, 8, 9]

您可以通过重写clone方法来自己处理深度复制来避免它。

于 2012-05-01T12:28:49.500 回答
0

Ruby 是非常面向对象的。除了极少数例外,Ruby 几乎总是通过引用而不是值来传递变量。这是一个非常重要的概念。看看这个。它不是红宝石,但它可能有助于揭开它的神秘面纱。希望有帮助!

于 2012-05-01T12:15:39.067 回答