我有
def initialize
@board = [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
end
我以为我可以缩短它:
def initialize
@board=[ [0] * 4] * 4
end
它们看起来一样,但只有后者,我得到一个错误,如:
10) vertical turn can add 1 to an existing column of 2 with 1's at the ends [20/18949]
Failure/Error: expect([game.board[0][2], game.board[1][2], game.board[2][2], game.board[3][2]]).to eq [0,1,0,0]
expected: [0, 1, 0, 0]
got: [1, 1, 0, 1]
(compared using ==)
# ./spec/game_spec.rb:132:in `block (2 levels) in <top (required)>'
答案 0 :(得分:5)
请尝试使用此工作和非工作代码:
@board.map { |x| x.object_id }
你会发现差异。发生错误是因为所有内部数组都是同一个对象。
问题在于
[ [0] * 4 ] * 4
是一个包含相同数组四次的数组。
虽然
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
是一个包含四个不同Array对象的Array。
当你.inspect
时,它们看起来是一样的,因为Ruby没有向你显示对象ID。
实现0-ed数组的另一种方法可能是:
Array.new(4) { Array.new(4) {0} }
或者,如果您只处理4x4整数,那么您可以查看narray
库,它没有这些问题,而且批量操作也非常快。