配列の初期化

Javaの場合

配列の初期化。Javaの場合、ループでまわして一つずつnewする。

Object[] a = new Object[3];

for (int i=0;i<3;i++) {
	a[i] = new Object();
}

Rubyの場合

こんなクラスの配列を作ることを考える。

class Foo
  def initialize
    @num = 0
  end
  def setNum(num)
    @num = num
  end
end
期待通りにならない例

これだと、同じ実体を参照するオブジェクトの配列になってしまう

a = Array.new(3, Foo.new)
a[0].setNum(1)
p a
  • 実行結果
[#<Foo:0x1002e864 @num=1>, #<Foo:0x1002e864 @num=1>, #<Foo:0x1002e864 @num=1>]

アドレスが全部おんなじになってる。numの値もすべて同じ。

うまくいく例

ブロックを渡して、毎回newするようにする。

a = Array.new(3){Foo.new}
a[0].setNum(2)
p a
  • 実行結果
[#<Foo:0x1002e684 @num=2>, #<Foo:0x1002e670 @num=0>, #<Foo:0x1002e65c @num=0>]

別々の物を指してるので、a[0]だけnumの値が変更されている。

応用例

多次元配列の場合はこんな感じ。

a = Array.new(2){ Array.new(3){Foo.new}}
a[1][1].setNum(5)
p a
  • 実行結果
[[#<Foo:0x1002ea08 @num=0>, #<Foo:0x1002e9f4 @num=0>, #<Foo:0x1002e9e0 @num=0>], [#<Foo:0x1002e9a4 @num=0>, #<Foo:0x1002e990 @num=5>, #<Foo:0x1002e97c @num=0>]]

以上。