如何解引用这个Perl数组的数组?

4
考虑以下这段 Perl 代码。
my @a=[[1]];

print $a[0][0];


**output**
ARRAY(0x229e8)

为什么它打印出一个ARRAY而不是1?我原本期望@a创建一个大小为1的数组,并引用另一个仅包含一个元素1的数组。

可能是重复问题:https://dev59.com/fXE85IYBdhLWcg3wRBRU#2860572 - Zaid
4个回答

14

这里的问题比较棘手。你将 @a 赋值为一个包含对数组引用的引用的列表,比你预期的多了一层间接引用。

如果想要得到期望的结果,你应该这样写:

@a = ( [ 1 ] );

11

你想要的值在 $a[0][0][0]。你正在将一个数组引用赋值为@a数组的第一个元素。

这是类似的事情:

my @a = 'scalar';

这将创建一个仅有1个元素的数组,其中该元素为字符串'scalar'。因此,当您将标量值赋给数组时,Perl会尝试按照您的意愿创建一个大小为1的列表,并将该标量值作为第一个元素。

另外,

my @a = undef;

这段代码做的是相同的事情,但第一个槽位是undef。你想要的是

my @a = [1];

4

我猜您想要写的是:

my $x = [[1]]; # reference to anon array containing
               # reference to anon array with one element

print $x->[0][0];

请参见Perl数据结构菜谱

我知道这并不特别重要,但$x->[0]->[0]是我喜欢的写法。 - Dan Beam
@Dan Beam:你为什么想要这样做呢?请参考https://dev59.com/2EzSa4cB1Zd3GeqPoanx。 - Zaid
因为只使用[]表示数组和数组引用容易导致混淆,但正如我所说-这并不特别重要。 - Dan Beam

3

mobrule、Axeman和Sinan都回答了你的问题:你创建了一个三层深度的数据结构,而不是两层。

我很惊讶没有人建议使用核心Data::Dumper库来帮助理解数据结构问题。

use Data::Dumper;

my @a = [[1]];
print Dumper \@a;

这将打印:

$VAR1 = [ [ [ 1 ] ] ];

你的错误是使用数组引用构造函数[],而不是只使用括号(或什么都不使用)。@a = ([1]);

那么,为什么Perl有奇怪的[]{}语法来声明哈希和数组引用呢?

这归结于Perl会展开列表。这意味着如果你说:@a = (@b, @c);,那么@a被赋值为@b的内容与@c的内容相连的结果。这与Python的extend列表方法相同。如果你想让@a有两个元素,你需要强制它们不要扩展。你可以通过对每个数组取一个引用来实现这一点:@a = (\@b, \@c);。这就像Python的append列表方法。

当你想创建匿名嵌套结构时,你需要有一种方法来标记它们是哈希还是数组。这就是我上面提到的语法的作用。

但是列表展开有什么好处呢?为什么值得为了制作数组和哈希引用而使用与正常初始化不同的不寻常语法呢?

列表展开意味着你可以轻松地在一个变量中组装一系列子例程参数,然后将它们传递而不需要做任何棘手的事情:foo(@some_args, 5, @more_args);。请参阅维基百科上关于此概念在其他语言中如何工作的信息。你可以使用map和其他函数做各种好玩的事情。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接