Perl 数组推送和引用
我是一名perl初学者,我遇到了一段代码,如下所示:Perl 数组推送和引用,perl,Perl,我是一名perl初学者,我遇到了一段代码,如下所示: my @Numbers=(); push(@{$Numbers[0]},3,8,9); push(@{$Numbers[1]},5); print join(",",@{$Numbers[0]}); print "\n"; print join(",",@{$Numbers[1]}); print "\n"; 我很难理解推送到{$Numbers[0]}和
my @Numbers=();
push(@{$Numbers[0]},3,8,9);
push(@{$Numbers[1]},5);
print join(",",@{$Numbers[0]});
print "\n";
print join(",",@{$Numbers[1]});
print "\n";
我很难理解推送到{$Numbers[0]}和{$Numbers[1]}上的操作是什么。推送是否会自动创建对数字数组中[3,8,9]和[5]的数组引用?我不难理解下面的语法,我认为这是更常见的语法,但我没有遇到我在上面粘贴的语法,我猜它也使用自动生动化来填充带有引用的数字数组
my @Numbers=();
push(@Numbers,[3,8,9]);
push(@Numbers,[5]);
print join(",",@{$Numbers[0]});
print "\n";
print join(",",@{$Numbers[1]});
print "\n";
使用Data::Dumper查看发生了什么
#! /usr/bin/perl
use Data::Dumper;
my @Numbers=();
push(@Numbers,[3,8,9]);
push(@Numbers,[5]);
print Dumper(@Numbers);
输出:
$VAR1 = [
3,
8,
9
];
$VAR2 = [
5
];
如果将数组传递给转储程序,则元素将被解释为多个参数
圆括号是数组,矩形括号是数组引用<代码>推送仅对数组有效,但对数组引用无效。有关引用和反引用的详细信息,请参阅Perl手册
可以使用反斜杠将数组转换为数组引用:
print Dumper(\@Numbers);
现在,Dumper用矩形括号显示引用
$VAR1 = [
[
3,
8,
9
],
[
5
]
];
您也可以将数字作为引用,但在将其传递给push之前,必须先取消引用
#! /usr/bin/perl
use Data::Dumper;
my $Numbers=[];
push(@$Numbers,[3,8,9]);
push(@$Numbers,[5]);
print Dumper($Numbers);
现在你会明白这一点:
push(@{$Numbers[0]},3,8,9);
获取数组的第一个元素(标量)$Numbers[0]
将标量反引用到数组中@{$Numbers[0]}
将三个标量push
、3
和8
追加到取消引用的数组中9
这将导致创建一个数组引用。有两个功能在发挥作用,其中一个确实是
我马上就要进行自我激活了。首先,让我们考虑当我们访问<代码> $编号[0 ] < /代码>时,<代码> @编号<代码>是空的。这不是问题。Perl将自动扩展数组以包含此元素。[1]
my@a;
$a[3]=123;#好啊
打印(转储程序(\@a));\[未定义,未定义,未定义,123]
这并不是文档中所说的“自生”,但它非常相似,有些人也会称之为“自生”
正如我提到的,第二个特征确实是自生。Autovification是通过取消引用自动创建匿名变量。具体来说,它发生在取消引用未定义的标量时。[2] 在这种情况下,Autovification会创建一个数组,因为
@BLOCK
是一个数组解引用。对该数组的引用将创建并存储在以前的未定义标量中
换言之,自生使得
push@{$ref},列表;
实际上相当于
push@{$ref/=[]},列表;
或
if(!defined($ref)){
我的@anon;
$ref=\@anon;
}
推送@$ref,列表;
这可能只是这个问题的一个人为的例子,但请注意,发布的代码很奇怪。我们知道
$Numbers[0]
和$Numbers[1]
是未定义的,所以我们不需要推送
my@nums;
@{$nums[0]}=(3,8,9);#还有自生。
@{$nums[1]}=5;
既然我们知道,$Numbers[0]
和$Numbers[1]
是未定义的,我们也就没有必要依赖于自动生命化
my@nums;
$nums[0]=[3,8,9];
$nums[1]=[5];
让我们去掉那些硬编码的索引
my@nums;
按@nums[3,8,9];
推送@nums,[5];
以及最后的简化
my@nums=(
[ 3, 8, 9 ],
[ 5 ],
);
打印数组或散列转储程序以了解结构。请参阅。@vkk05使用Data::Dumper打印数组。看起来第一个和第二个示例完全相同。两者都在数字数组中创建两个引用。只是第一个例子和语法并不常见——至少我在任何地方都没有见过。如果你像使用排序字典一样使用
@Numbers
,第一个例子是有意义的,其中键是数字。然后您可以稍后push@{$Numbers[$NumericKey]}、@AdditionalNumbers代码>(请注意,索引序列中有“间隙”是有效的)提示:清空空数组没有意义<代码>我的@Numbers=()代码>简化为my@number代码>Re“圆括号是数组”,完全错误<代码>()
与数组无关。帕伦夫妇只是像在数学中那样改变优先级。例如,my@a=4代码>,my@a=4..5代码>,等等,我们只在my@a=(4,5)中使用它们代码>因为它的意思是(my@a=4),5代码>否则<代码>我的@a
是[]
的命名等价物,而不是()
。是的,未定义的标量就是标量。数组和散列值是标量。@sdp,是的<代码>推送{$Numbers[0]},3,8,9
实际上是push@{$Numbers[0]/=[]}、3、8、9的缩写代码>,我们称之为自生。在底部的解释中缺少了一个步骤,当使用未定义的标量作为引用时,会自动创建一个数组。我不打算这样做,因为我认为这个答案很好地解释了代码的功能。但这不是OP的问题。他们特别询问关于自体移植的问题,而你似乎正在为此而挣扎。我刚刚发布了一个答案。你让我说了11遍“自动激活”。把它改成12。