Perlには、他のいくつかの言語のように多次元配列を表現するための組み込み構文はありません。代わりに、配列の配列を使用します。ここで、最上位の要素は別の配列への参照です。このような構成により、テーブル、マトリックス、またはより深い入れ子構造を必要とする他のデータ構造を柔軟にモデル化できます。
最初は、Perlはテキスト処理と単純な構造の操作のために開発されましたが、Perl 5以降、参照が導入されたことで、開発者は配列の配列や配列のハッシュなどの複雑な入れ子の構造を構築できるようになりました。
新しいユーザーにとっての主な誤解は、2次元配列を単純な方法で作成しようとすることです。たとえば、@matrix = ( (1,2), (3,4) )と宣言することです。このアプローチでは、要素がスカラ値として展開され、入れ子になった構造にはなりません。また、配列をコピーする際に起こるエラーもよくあります。浅いコピーは予期しない副作用を引き起こす可能性があります。
Perlでは、多次元配列は配列への参照を通じて構築されます。正しい初期化は次のようになります:
my @matrix; for my $i (0..2) { for my $j (0..2) { $matrix[$i][$j] = $i * $j; } } # 要素にアクセスする:$matrix[1][2]
または、匿名参照を使用します:
my $matrix = [ [1,2,3], [4,5,6], [7,8,9] ]; print $matrix->[1][2]; # 6
主な特徴:
他の言語のように、単に括弧の中に括弧を宣言することで多次元配列を作成できますか?
いいえ。この場合、Perlは要素を通常のリストとして解決します。参照を使用することだけが正しいです。
誤ったコードの例:
my @matrix = ((1,2,3),(4,5,6),(7,8,9)); # 要素が一列になる print $matrix[3]; # 4、ではなく[4,5,6] — 不正な動作
正しい方法:
my @matrix = ( [1,2,3], [4,5,6], [7,8,9] ); print $matrix[1][2]; # 6
配列の配列を単純な代入でコピーするとどうなりますか?
最上位レベルだけがコピーされ、入れ子の配列は同じメモリ領域を参照します。
例:
my @a = ( [1,2], [3,4] ); my @b = @a; $a[0][0] = 99; print $b[0][0]; # 99、期待していたのは1 — 浅いコピー!
Perlの組み込み機能で入れ子の配列を「深く」コピーできますか?
いいえ。Perlは入れ子構造のための標準的な深いコピー演算子を提供していません。Storableモジュールまたは再帰関数を使用する必要があります。
Storableを使用した例:
use Storable 'dclone'; my $deepcopy = dclone(\@matrix);
開発者が単純な配列宣言で2次元マトリックスを作成し、それを代入でコピーします:
my @m1 = ([1,2],[3,4]);
my @m2 = @m1;
$m1[0][0] = 77;
print $m2[0][0];
利点:
欠点:
Storableモジュールを使用して深いコピーを行う:
use Storable 'dclone'; my @m1 = ([1,2],[3,4]); my $m2 = dclone(\@m1); $m1[0][0] = 77; print $m2->[0][0]; # 1
利点:
欠点: