我在Perl中有两个数据结构:
数组:
my @array2 = ( "1", "2", "3");
for $elem (@array2) {
print $elem."\n";
}
给我以下输出:
1
2
3
列表:
my @array = [ "1", "2", "3"];
for $elem (@array) {
print $elem."\n";
}
提供以下输出:
ARRAY(0x9c90818)
显然,我想在两种情况下迭代元素,但为什么第二种解决方案只给我这个数组的引用?
答案 0 :(得分:80)
Perl中的列表不是数据结构,它们是源代码中的位置,由它们周围的上下文决定。列表基本上是Perl用于移动数据的瞬态结构。您使用Perl的所有语法与它们进行交互,但您无法将它们作为数据类型使用。最接近列表的数据类型是数组。
my @var = (1, 2, 3); # parens needed for precedence, they do not create a list
^ an array ^ a list
say 1, 2, 3;
^ a list
say @var;
^ a list (of one array, which will expand into 3 values before `say` is called)
当你写[1, 2, 3]
时,你正在做的是创建一个标量数组引用。使用列表1, 2, 3
初始化该数组引用,它与创建命名数组并引用它相同:
[1, 2, 3] ~~ do {my @x = (1, 2, 3); \@x}
由于[...]
构造创建标量,您应该将其保存在标量中:
my $array = [1, 2, 3];
for my $elem (@$array) { # lexical loop variable
print $elem."\n";
}
由于您希望对整个数组(而不仅仅是引用)进行操作,因此在@
前面放置一个$array
,它取消引用存储的数组引用。
答案 1 :(得分:31)
方括号用于创建匿名数组。在计算时,它返回对此数组的引用,而不是实际的数组值。
圆括号没有这样的隐藏属性,只是简单地覆盖表达式中的precedence,就像在数学中一样。例如:
my @array = 1,2,3;
实际上是这样评估的:
my @array = 1;
2,3; # causes the warning "Useless use of constant in void context"
因为=
运算符的优先级高于逗号。因此,为了解决这个问题,我们在分配数组时使用括号,如下所示:
my @array = (1,2,3);
你的例子:
my @array = [1,2,3];
有点像这样说:
my @tmp = (1,2,3);
my @array = \@tmp;
\
用于创建对@tmp
数组的引用。
答案 2 :(得分:7)
方括号创建一个匿名数组,使用括号的内容填充数组,并返回对该数组的引用。换句话说,
[ "1", "2", "3" ]
与
基本相同do { my @anon = ("1", "2", "3"); \@anon }
所以代码看起来应该是
my $array_ref = [ "1", "2", "3" ];
for (@$array_ref) { # Short for @{ $array_ref }
print "$_\n";
}
或
my @array_of_refs = ([ "1", "2", "3" ]);
for my $array_ref (@array_of_refs) {
for (@$array_ref) {
print "$_\n";
}
}
答案 3 :(得分:4)
如果您需要更多说明,请参阅the relevant documentation。
你可以尝试做一些事情用于说明目的:
#!perl -lw # -l appends a \n to each print, -w enables warnings
use strict;
my $aryref = [1 .. 5];
print for $aryref; # Prints the stringified reference - not what you want
print for @$aryref; # Dereferencing it lets you access the array
my @ary = $aryref; # Probably not what you want
print for @ary; # Stringified reference again
print for @{$ary[0]}; # Dereference the first array element (which holds the ref)
答案 4 :(得分:0)
在Perl中,数组和列表基本相同,但第二个示例不使用。方括号围绕数组引用(标量值),并且使用my @array = $scalar
之类的数组“标记”标量等同于my @array = ($scalar)
。因此,第二个示例中@array
的唯一元素是数组引用。
答案 5 :(得分:0)
@array =(“1”,“2”,“3”); 这里1,2,3是@array变量的元素。对于前者$ array [0]为1,$ array [1]为2,$ array [2]为3。
@array = [“1”,“2”,“3”];
Perl使用[]使用匿名数组引用,所以这里基本上只存储一个元素,这是@array变量的数组[“1”,“2”,“3”]的引用。对于ex $ array [0]是“ARRAY(0x9c90818)”
因此,在打印时,它会向您显示参考。