任何人都可以向我解释以下Perl代码中的push
语句吗?我知道perl如何工作但我无法理解跟随push命令的第一个参数代表什么。我试图解释某人的剧本。我尝试print "@a\n";
,但它只打印ARRAY(0x9aa370)
,这让我觉得推动没有做任何事情。任何帮助表示赞赏。谢谢!
my @a = ();
my $b = 10;
my $c = 'a';
push(@{$a[$b]}, $c);
答案 0 :(得分:13)
让我们分解吧。
从"Using References" in perlref
了解@{...}
在您将标识符(或标识符链)作为变量或子例程名称的一部分放置的任何地方,您可以使用BLOCK替换标识符,返回正确类型的引用。
那么{ ... }
块内部的内容最好用于数组引用。您在那里$a[$b]
,索引为@a
的{{1}}元素,因此该元素必须是arrayref。
然后$b
取消引用它,并@{...}
为其添加新元素push
。总而言之,$c
被复制到匿名数组的(唯一)元素中,该数组的引用位于数组$c
的索引$b
。
并且关键部分:因为实际上没有arrayref †,autovivification开始并且它被创建。由于在@a
之前的索引处没有元素,因此它们也会被创建,值为$b
。
现在请完成工作
教程perlreftut和
数据结构食谱perldsc
在开始时使用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]