当我尝试从数组中弹出一个元素时,它会弹出。当我在弹出之前将该数组分配给另一个变量然后如果我弹出时,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,则所有变量都会受到影响。我想保留原始数组并弹出另一个数组。怎么样?
答案 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。它不是红宝石,但它可能有助于揭开它的神秘面纱。希望有所帮助!