Perl中的引用如何工作

时间:2017-08-24 22:40:33

标签: perl

任何人都可以向我解释以下Perl代码中的push语句吗?我知道perl如何工作但我无法理解跟随push命令的第一个参数代表什么。我试图解释某人的剧本。我尝试print "@a\n";,但它只打印ARRAY(0x9aa370),这让我觉得推动没有做任何事情。任何帮助表示赞赏。谢谢!

my @a = (); 
my $b = 10;
my $c = 'a';
push(@{$a[$b]}, $c);

3 个答案:

答案 0 :(得分:13)

让我们分解吧。

"Using References" in perlref

了解@{...}
  

在您将标识符(或标识符链)作为变量或子例程名称的一部分放置的任何地方,您可以使用BLOCK替换标识符,返回正确类型的引用。

那么{ ... }块内部的内容最好用于数组引用。您在那里$a[$b],索引为@a的{​​{1}}元素,因此该元素必须是arrayref。

然后$b取消引用它,并@{...}为其添加新元素push。总而言之,$c被复制到匿名数组的(唯一)元素中,该数组的引用位于数组$c的索引$b

并且关键部分:因为实际上没有arrayref autovivification开始并且它被创建。由于在@a之前的索引处没有元素,因此它们也会被创建,值为$b

现在完成工作

在开始时使用undef链接进行完整参考。

对于复杂的数据结构,能够看到它们很有用,并且有适合的工具。最常用的是核心Data::Dumper,这是Data::Dump

的示例
perlref

带输出

[1, undef, undef, ["ah"]]

其中perl -MData::Dump=dd -wE'@ary = (1); push @{$ary[3]}, "ah"; dd \@ary' 表示一个arrayref,其唯一元素是字符串[]

更确切地说,ah标量被解除引用,因为这发生在 lvalue 上下文中,自动生成就会发生。感谢ikegami发表评论。例如,请参阅this post及其链接。

答案 1 :(得分:3)

让我们从以下两个断言开始:

  • @a从一个没有元素的空数组开始。
  • $b的值为10.

现在看看这个结构:

@{$a[$b]}

要理解我们可以从中间开始:$a[$b]索引数组@a的元素10。

现在我们可以从那里开始工作:@{...}将其内容视为对数组的引用。因此@{$a[$b]}将数组@a的元素10的内容视为对匿名数组的引用。也就是说,$a[10]中包含的标量值是数组引用。

现在在推送中进行分层:

push @{$a[$b]}, $c;

@a的元素10中引用的匿名数组中,您正在推送$c的值,即{#1};"。您可以像这样访问该元素:

my $value = $a[10]->[0]; # character 'a'

或简写,

my $value = $a[10][0];

如果您将另一个值推入@{$a[10]},那么您可以访问:

my $other_value = $a[10][1];

$a[0]$a[9]呢?您只是将值推送到$a[$b],即$a[10]。 Perl自动扩展数组以适应第11个元素($a[10]),但将$a[0]$a[9]的值保留为undef。你提到过你试过这个:

print "@a\n";

将数组插入到字符串中会导致其元素在每个元素之间打印一个空格。所以你没有看到这个:

ARRAY(0xa6f328)

你看到了这个:

ARRAY(0xa6f328)

...因为在包含数组引用的第11个元素之前有10个空格。

如果您在顶部使用use warnings运行脚本,则可能会看到此内容:

Use of uninitialized value in join or string at scripts/mytest.pl line 12.
Use of uninitialized value in join or string at scripts/mytest.pl line 12.
Use of uninitialized value in join or string at scripts/mytest.pl line 12.
Use of uninitialized value in join or string at scripts/mytest.pl line 12.
Use of uninitialized value in join or string at scripts/mytest.pl line 12.
Use of uninitialized value in join or string at scripts/mytest.pl line 12.
Use of uninitialized value in join or string at scripts/mytest.pl line 12.
Use of uninitialized value in join or string at scripts/mytest.pl line 12.
Use of uninitialized value in join or string at scripts/mytest.pl line 12.
Use of uninitialized value in join or string at scripts/mytest.pl line 12.
          ARRAY(0xa6f328)

......或类似的东西。

您的结构目前看起来像这样:

@a = (undef,undef,undef,undef,undef,undef,undef,undef,undef,undef,['a'])

如果您想真正了解数据结构的外观,而不是使用简单的打印,请执行以下操作:

use Data::Dumper;
print Dumper \@a;

答案 2 :(得分:1)

昨天我对此进行了讨论here

这意味着什么 @a是一个数组

$a[$b]

是数组中的一个单元格 @{}语法有助于perl了解相关单元格是一个数组,因此您可以对其执行推/弹操作。
如果你这样做

use Data::Dumper;
print Dumper \@a;
你应该看到类似的东西:

$VAR1 = [
          undef,
          undef,
          undef,
          undef,
          undef,
          undef,
          undef,
          undef,
          undef,
          undef,
          [
            'a'
          ]
        ];

如您所见,第11个单元格是一个包含字母“a”作为其唯一值的数组 空单元格上的推送操作也可以写成:

$a[$b] = [$c]