为什么我不能在方法中修改数组的值?

时间:2011-05-11 15:28:53

标签: ruby arrays

在下面的代码片段中,数组deck应该等于[6,9,5,6,5,1,2],因为Ruby通过引用传递数组。方法调用后,deck的值不会改变。那是为什么?

def count_cut!(deck)
  s1, s2 = deck[0, deck.last], deck[deck.last..-2]
  deck = s2 + s1 + [deck.last]
end

deck = [5, 1, 6, 9, 5, 6, 2]
count_cut!(deck)
p deck

我使用的是Ruby 1.9.2-p180。

4 个答案:

答案 0 :(得分:8)

分配给deck不会改变传入的数组。它被视为函数定义范围内的局部变量。如果你真的想改变它,你可以致电deck.replace

答案 1 :(得分:5)

以Ruby方式执行:不是修改原始数组,而是返回修改后的数组:

def count_cut(deck)
  s1, s2 = deck[0, deck.last], deck[deck.last..-2]
  s2 + s1 + [deck.last]
end

然后,调用者将返回值分配给deck

deck = [5, 1, 6, 9, 5, 6, 2]
deck = count_cut(deck)
p deck

但是考虑将它全部封装在Deck类中,特别是如果牌组有其他行为:

class Deck

  def initialize(cards)
    @cards = cards
  end

  def count_cut!
    s1, s2 = @cards[0, @cards.last], @cards[@cards.last..-2]
    @cards = s2 + s1 + [@cards.last]
  end

end

deck = Deck.new [5, 1, 6, 9, 5, 6, 2]
deck.count_cut!
p deck

答案 2 :(得分:2)

Array的。+方法可以获得 new 数组。使用.unshift修改原始对象。

deck = [1,2,3,4,5]
p deck.object_id #some_number
deck = [6] + deck
p deck.object_id #another_number
deck.unshift([7])
p deck.object_id #unchanged 

答案 3 :(得分:1)

您没有修改deck变量引用的数组,您只是将新数组赋给局部变量deck

deck = s2 + s1 + [deck.last]

上面创建了一个内容为s2 + s1 + [deck.last]的新数组,然后将这个新数组分配给局部变量deckdeck最初引用的数组保持不变。如果你想改变数组,那么你需要这样的东西:

deck_last = deck.last
deck.clear
deck.push(*s2)
deck.push(*s1)
deck.push(deck_last)

或者你失去了局部变量deck和它引用的非局部数组之间的连接。