配列の初期化
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>]]
以上。