Mar*_*lke 41 arrays perl perl-data-structures
我在Perl中有两个数据结构:
数组:
my @array2 = ( "1", "2", "3");
for $elem (@array2) {
print $elem."\n";
}
Run Code Online (Sandbox Code Playgroud)
给我以下输出:
1
2
3
Run Code Online (Sandbox Code Playgroud)
还有一个清单:
my @array = [ "1", "2", "3"];
for $elem (@array) {
print $elem."\n";
}
Run Code Online (Sandbox Code Playgroud)
给出以下输出:
ARRAY(0x9c90818)
Run Code Online (Sandbox Code Playgroud)
显然,我想在两种情况下迭代元素,但为什么第二种解决方案只给我这个数组的引用?
Eri*_*rom 81
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)
Run Code Online (Sandbox Code Playgroud)
当你写下[1, 2, 3]你正在做的是创建一个标量数组引用.该数组引用是使用列表初始化的1, 2, 3,它与创建命名数组并引用它相同:
[1, 2, 3] ~~ do {my @x = (1, 2, 3); \@x}
Run Code Online (Sandbox Code Playgroud)
由于该[...]构造创建了一个标量,因此您应该将其保存在标量中:
my $array = [1, 2, 3];
for my $elem (@$array) { # lexical loop variable
print $elem."\n";
}
Run Code Online (Sandbox Code Playgroud)
由于您希望对整个数组进行操作,而不仅仅是引用,因此您需要@在其前面放置一个$array取消引用存储的数组引用.
TLP*_*TLP 32
方括号用于创建匿名数组.在计算时,它返回对此数组的引用,而不是实际的数组值.
括号没有这样的隐藏属性,但只是覆盖表达式中的优先级,就像在数学中一样.例如:
my @array = 1,2,3;
Run Code Online (Sandbox Code Playgroud)
实际上是这样评估的:
my @array = 1;
2,3; # causes the warning "Useless use of constant in void context"
Run Code Online (Sandbox Code Playgroud)
因为=运算符的优先级高于逗号.因此,为了解决这个问题,我们在分配数组时使用括号,如下所示:
my @array = (1,2,3);
Run Code Online (Sandbox Code Playgroud)
你的例子:
my @array = [1,2,3];
Run Code Online (Sandbox Code Playgroud)
有点像这样说:
my @tmp = (1,2,3);
my @array = \@tmp;
Run Code Online (Sandbox Code Playgroud)
其中\用于创建对@tmp数组的引用.
方括号创建一个匿名数组,使用括号的内容填充数组,并返回对该数组的引用.换一种说法,
[ "1", "2", "3" ]
Run Code Online (Sandbox Code Playgroud)
基本上是一样的
do { my @anon = ("1", "2", "3"); \@anon }
Run Code Online (Sandbox Code Playgroud)
所以代码应该是这样的
my $array_ref = [ "1", "2", "3" ];
for (@$array_ref) { # Short for @{ $array_ref }
print "$_\n";
}
Run Code Online (Sandbox Code Playgroud)
要么
my @array_of_refs = ([ "1", "2", "3" ]);
for my $array_ref (@array_of_refs) {
for (@$array_ref) {
print "$_\n";
}
}
Run Code Online (Sandbox Code Playgroud)
如果您需要更多说明,请参阅相关文档。
为了说明目的,您可以尝试做一些事情:
#!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)
Run Code Online (Sandbox Code Playgroud)