在Perl中没有内置的语法来实现多维数组,像其他某些语言那样。相反,使用数组的数组,每个顶层元素都是指向另一个数组的引用。这种组织方式允许灵活地建模表格、矩阵和其他需要二维或更高嵌套的结构。
最初,Perl是为了处理文本和简单结构而开发的,但自从出现引用(从Perl 5开始),开发者就能够构建复杂的嵌套结构,例如数组的数组或哈希数组。
新用户的主要误解是:尝试通过简单的方式创建二维数组——例如,声明@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);
开发者通过简单的数组声明创建二维矩阵,并通过赋值进行复制:
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
优点:
缺点: