ruby pop数组,不影响其他变量

时间:2012-05-01 11:59:40

标签: ruby arrays pop

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

例如:

 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,则所有变量都会受到影响。我想保留原始数组并弹出另一个数组。怎么样?

3 个答案:

答案 0 :(得分: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] 

答案 1 :(得分:3)

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

不要忘记,dup(和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方法来自行处理深层复制来避免它。

答案 2 :(得分:0)

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