我用这种方式创建了一个多维数组:
#!/usr/bin/perl
use warnings;
use strict;
my @a1 = (1,2);
my @a2 = (@a1,3);
但事实证明我仍然有一个一维数组...
perl的正确方法是什么?
答案 0 :(得分:9)
你得到一维数组,因为数组@a1
在parens中扩展。所以,假设:
my @a1 = (1,2);
my @a2 = (@a1,3);
然后你的第二个陈述相当于my @a2 = (1,2,3);
。
创建多维数组时,您有几个选择:
第一个选项基本上是$array[0][0] = 1;
不是很令人兴奋。
第二个是这样做:my @a2 = (\@a1, 3);
请注意,这会引用数组@a1
的命名空间,因此如果您稍后更改@a1
,@a2
中的值也会改变。并不总是推荐选项。
第二个选项的变体是这样做的:my @a2 = ([1,2], 3);
括号将创建一个匿名数组,它没有命名空间,只有一个内存地址,并且只存在于@a2
内。
第三个选项,有点模糊,正在执行此操作:my $a1 = [1,2]; my @a2 = ($a1, 3);
它将完成与2完全相同的操作,只有数组引用已经在标量变量中,称为$a1
。< / p>
注意分配给数组时()
和[]
之间的区别。括号[]
创建一个匿名数组,它返回一个数组引用作为标量值(例如,可以由$a1
或$a2[0]
保存)。
考虑这段代码:
my @a2 = 1, 2, 3;
print "@a2";
这将打印1
。如果您use warnings
,您还会收到警告,例如:Useless use of a constant in void context
。基本上会发生什么:
my @a2 = 1;
2, 3;
因为逗号(,
)的优先级低于等号=
。 (参见perldoc perlop)
parens做的只是在列表中将=
和,
以及组1,2,3
的默认优先级否定,然后传递给@a2
。
因此,简而言之,括号[]
有一些神奇之处:它们创建了匿名数组。 Parens ()
只是改变了优先级,就像在数学中一样。
文档中有很多内容需要阅读。这里曾经有人向我展示了一个非常好的解除引用链接,但我不记得它是什么。在perldoc perlreftut中,您将找到有关参考的基本教程。在perldoc perldsc中,您将找到有关数据结构的文档(感谢Oesor提醒我)。
答案 1 :(得分:6)
我建议通过perlreftut
, perldsc
and perllol
,最好是在同一天,最好使用Data::Dumper
来打印数据结构。
教程相互补充,我认为它们会更好地结合起来。可视化数据结构帮助我很多人相信他们实际工作(认真)并看到我的错误。
答案 2 :(得分:4)
答案 3 :(得分:2)
最重要的是要理解 关于中的所有数据结构 Perl - 包括多维 数组 - 即使他们可能 否则,Perl @ARRAY 和 %HASH es都在内部 一维的。他们只能持有 标量值(表示字符串, 数字或参考)。他们不能 直接包含其他数组或 哈希,而是包含引用 到其他阵列或哈希。
现在,因为顶级只包含引用,如果你尝试使用简单的print()函数打印出你的数组,你会得到看起来不太好的东西,如下所示:
@AoA = ( [2, 3], [4, 5, 7], [0] );
print $AoA[1][2];
7
print @AoA;
ARRAY(0x83c38)ARRAY(0x8b194)ARRAY(0x8b1d0)
那是因为Perl不会(永远)隐式取消引用您的变量。如果你想得到一个引用引用的东西,那么你必须自己使用前缀类型指示符,如${$blah} , @{$blah} , @{$blah[$i]}
,或者后缀指针箭头,如$a->[3] , $h->{fred}
,甚至{ {1}}
来源:perldoc
现在回答你的问题。这是你的代码:
$ob->method()->[3]
请注意,数组包含标量值。因此,您必须使用引用,并且可以在要引用的数组名称之前使用my @a1 = (1,2);
my @a2 = (@a1,3);
关键字添加引用。
像这样:
\
答案 4 :(得分:1)
内部数组应该是外部数组中的标量引用:
my @a2 = (\@a1,3); # first element is a reference to a1
print ${$a2[0]}[1]; # print second element of inner array
答案 5 :(得分:0)
这是2D数组的简单示例,如
my $AoA=undef;
for(my $i=0;$i<3;$i++) {
for(my $j=0;$j<3;$j++) {
$AoA->[$i]->[$j] = rand(); #assign some value
}
}