48

我在 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)

显然,我想在这两种情况下迭代元素,但为什么第二种解决方案只给我这个数组的引用?

4

6 回答 6

87

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]你正在做的是创建一个标量数组引用。该数组引用是用 list 初始化的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";
}

由于您想对整个数组进行操作,而不仅仅是引用,因此您将 a放在取消引用存储的数组引用的@前面。$array

于 2011-05-16T22:44:15.083 回答
38

方括号用于创建匿名数组。计算时,它返回对该数组的引用,而不是实际的数组值。

括号没有这样的隐藏属性,只是简单地覆盖表达式内部的优先级,就像在数学中一样。例如:

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数组的引用。

于 2011-05-16T22:52:17.400 回答
8

方括号创建一个匿名数组,用方括号的内容填充数组,并返回对该数组的引用。换句话说,

[ "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";
    }
}
于 2011-05-16T23:24:39.333 回答
5

如果您需要更多说明,请参阅相关文档

出于说明目的,您可以尝试做一些事情:

#!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)
于 2011-05-16T22:20:48.017 回答
0

在 Perl 中,数组和列表本质上是相同的,但您的第二个示例都没有使用。方括号包围数组引用(标量值),并且将标量“分配”给具有my @array = $scalar类似my @array = ($scalar). 因此,第二个示例中的唯一元素@array是数组引用。

于 2011-05-16T21:49:40.767 回答
0

@array = ("1","2","3"); 这里 1,2,3 是 @array 变量的元素。例如。$array[0] 是 1 , $array[1] 是 2 并且 $array[2] 是 3。

@array = ["1","2","3"]; Perl 使用 [ ] 使用匿名数组引用,因此这里基本上只存储一个元素,即数组 ["1","2","3"] 对 @array 变量的引用。例如 $array[0] 是 "ARRAY(0x9c90818)"
因此在打印时它会显示参考。

于 2017-03-30T08:55:05.627 回答