引用对于创建二维乃至n维表是非常重要的。
1、创建引用
值和引用的区别有点像文件和目录的差别。和目录相比,引用还要根据值的类型进行分类,包括标量、数组、散列、子程序、句柄等。多级引用就像一棵树,最高级可看作引用的根。根是第一维,第一维可以只有一个数据,也可以有多个数据。
使用反斜杠创建引用
??? $a=$b;
??? $a=@b;
??? @a=(@b,%c);
直接生成匿名引用
??? $a=[1..3];??? #生成一个数组引用
??? $a={a..f};??? #生成一个散列引用
两种引用的差别
????$a=@b;??? #生成一个指向数组b的引用。当数组b的值变化时,变量a所代表的值同时发生变化。
????$a=[@b]; ??? #先将数组b展开,再生成一个匿名引用赋予变量a。当数组b的值变化时,变量a所代表的值不变。
2、调用引用的值
调用引用和查找文件需要指明路径一样,即使用合适的方法表示查找这个值的路径,这个路径可有多个级别,每个级别又分为多个类型。
使用变量类型字符,根据级别顺序使用相应类型的符号。从左往右即从分支到根部。在这里第一维只能是一个点(不能有下标)。
??? $b=(1..3); $a=@b;??? #引用赋予简单标量变量
????print "@$an";??? #输出123
????@$a[4..6]=(a..c); print "@$an@$a[2]n";??? #第一行为123abc,第二行为3。
??? #当引用赋予数组或散列则不能这样调用
使用{}把变量名变为带下标的形式,数据类型在{}左侧标识。
??? @b=(1..3); %c=(4..9); @a=(@b,%c);
????print keys %{$a[1]},"n";??? #输出"864"
????@{$a[0]}[4..6]=(a..c); print @{$a[0]},"n";??? #输出"123abc"
使用"->"由左往右逐级标识根部到末端的各级,不同级别的类型由括号的类型区别。
????@b=(1..3); %c=(4..9); @a=(@b,%c); @{$a[0]}[4..6]=(a..c);
????print $a[1]->{4},"n";??? #输出5
????print $a[1]{4},"n";??? #和前者一样,因为中括号和大括号之间的"->"可省。
??? 注意:$x[2][3]有两种解释,一种$x[2]->[3],一种$x->[2]->[3]。具体情况应在使用之前预设。
使用辨析
??? $a=[1..5];
????print $a;??? #输出一个表示数组引用的字符串,如ARRAY(...)
??? print @$a;??? #输出12345
??? print @{$a};??? #输出12345
??? print $a->[1];??? #输出2
??? @a=[1..5];
??? print @a;??? #输出ARRAY(...)
??? print $a[1];??? #无输出。因为引用本身是一个标量值,赋值给了数组a的第一个元素。
??? print scalar @a;??? #输出1
??? print $a[0];??? #输出ARRAY(...),代表1..5的引用
??? print $a[0]->[0];??? #输出1。
??? print $a[0][0];??? #输出1。省略了'->'
??? print @{$a[0]}[0];??? #输出1。使用{}标识带下标的变量名
??? print @{$a[0]};??? #输出12345
????@a=[[6..9],1..5];
??? print $a[0]->[0];??? #输出ARRAY(...)
??? print @{$a[0]->[0]};??? #输出6789
????print scalar @a;??? #输出1
????@a=([6..9],[1..5]);
????print scalar @a;??? #输出2
??? print $a[1]->[1];??? #输出2
??? print $a->[1]->[1];??? #无输出。因为第一维引用是@a,而不是$a
??? print $a[1][1];??? #和$a[1]->[1]一样
3、其他注意事项 3.1 对于一个多维数据来说,最好在开始就确定维度的个数,避免临时增加维度。 ??? 把一个已赋值的非引用类型的变量强行变为引用,可能会产生意外情况。 3.2 不要把引用作为散列的键 3.3 对数组和散列引用的循环建议采用以下形式 ??? print for (0 .. $#{$a[$b][$c]}); ??? print for (keys %{$a{$b}[$c]});