我试图以各种方式使用对数组的引用,我理解可以这样做。
这是我的一个试验: -
my $RoR = [[2, 3], [4, 5, 7]];
my @AoA = ([2, 3], [[2, 3], [4, 5, 7]]);
my @AwR = ([2, 3], @{$RoR});
print $AoA[1][1][1], "\n"; # 1
print $AoA[1]->[1][1], "\n"; # 2
#print $RoR[0][1], "\n"; # 3
print $RoR->[0][1], "\n"; # 4
print $AwR[1][1][1], "\n"; # 5
print $AwR[1]->[1][1], "\n"; # 6
如您所见,我有三个不同的阵列。
$RoR
- >是对匿名数组的引用,它包含两个匿名数组
@AoA
- >是一个包含2个匿名数组的数组。第二个匿名数组与引用$RoR
@AwR
- >与@AoA
几乎相同,但区别在于,我在其中添加了引用@{$RoR}
,而不是使用新的匿名数组。所以,基本上我认为,最后两个数组实际上是相同的。
现在,问题是,他们的行为方式不一样。
打印报表1
和2
工作正常,并打印出值5
作为结果。
打印语句3
给出错误,我知道原因,所以没问题。打印语句4
正在按预期打印值3
。
现在,当我尝试运行程序时,打印语句5
和6
会出现一些错误。
"Can't use string ("2") as an ARRAY ref while \"strict refs\" in use at
D:/_Perl Practice/3perldsc/array_of_array.pl line 15."
然后我尝试使用: -
print $AwR[1][1]->[1], "\n";
print @{$RoR}[1]->[1];
在哪里,我将$AwR[1]
替换为@{$RoR}
,因为$AwR[1]
包含@{$RoR}
。第二个工作正常,而第一个仍然是错误。
那么,1st two
和last two
打印语句之间究竟有什么区别?我认为它们是相同的,因此应该为相同的索引访问提供相同的结果。但事实并非如此。我是以错误的方式使用引用吗?
好的,现在有疑问是显而易见的。所以,我已经发布了一个答案,积累了与这个问题相关的一般内容。请看下面的内容。在那,我对5th and 6th
打印声明有疑问,为了理解它,我尝试了下面的测试: -
print $AwR[1][1]; # Allowed as `$AwR[1]` is same as `$$RoR`.
print $$RoR[1]; # Allowed as in 3(b)
print $AwR[1]->[1]; # Confused here. It is allowed
print $$RoR->[1]; # But this is not.
前三个语句正在打印相同的reference value
。但最后一个失败了。因此,确定: - $AwR[1]
与$$RoR
相同。但是,为什么$$RoR->[1]
在$AwR[1]->[1]
工作时无效?它给我这个错误: -
Not a SCALAR reference at D:/_Perl Practice/3perldsc/array_of_array.pl line 24.
那么,以两种不同的方式使用它有什么不同?
答案 0 :(得分:5)
在@AwR
分配您取消引用您对匿名数组$RoR
的引用时,您基本上会明白此行为:
my @AwR = ([2, 3], [2, 3], [4, 5, 7]);
不期望:
my @AwR = ([2, 3], [[2, 3], [4, 5, 7]]);
<强>更新强>
如果我们有多维数组(数组数组,AoA),那么之后的每个维度都必须是一个引用。因此,没有必要明确使用解除引用箭头,但它是允许的。因此,如果我们将AoA
作为参考,我们需要取消引用第一维维度,我们可以采用两种方式$$AoA
或$AoA->
,但我们不能将其解除引用两次,因为您注意到(示例中为$$RoR->[1]
)。
任何以下维度我们都可以省略解除引用箭头,当我们需要某个元素的地址时,所以有两个等价的用法:
my @AoA = ([2, 3], [ [2, 3], [4, 5, 7, [11, 12, [111, 112] ] ] ], [0]);
print "A: $AoA[1][1][3][2][0] \n"; # == 111
print "B: $AoA[1]->[1]->[3]->[2]->[0] \n"; # == 111
或AoA
作为参考
my $AoA = [ [2, 3], [ [2, 3], [4, 5, 7, [11, 12, [111, 112] ] ] ], [0] ];
print "A: $$AoA[1][1][3][2][0] \n"; # == 111
print "B: $AoA->[1]->[1]->[3]->[2]->[0] \n"; # == 111
答案 1 :(得分:3)
看来你期望@AoA和@AwR是相同的,但事实并非如此。您可以通过简单的测试脚本看到这一点:
#!/usr/bin/perl
use strict;
use warnings;
use Test::More;
my $RoR = [[2, 3], [4, 5, 7]];
my @AoA = ([2, 3], [[2, 3], [4, 5, 7]]);
my @AwR = ([2, 3], @{$RoR});
is_deeply(\@AwR, \@AoA, 'arrays match');
这是因为您将$ RoR插入@AwR的方式。要创建一个与@AoA相同的数组,请创建@AwR而不取消引用$ RoR:
my @newAwR = ([2, 3], $RoR);
并测试以确认这是正确的:
is_deeply(\@newAwR, \@AoA, 'arrays match');
答案 2 :(得分:1)
好的,现在我明白了,我想我会发布我的答案: -
use strict;
use warnings;
use Test::More;
my $RoR = [[2, 3], [4, 5, 7]];
my @AoA = ([2, 3], [[2, 3], [4, 5, 7]], [0]);
my @AwR = ([2, 3], $RoR, [0]);
print "1: ", $AoA[1][1][1], "\n"; # 1
print "2: ", $AoA[1]->[1][1], "\n"; # 2
#print "3(a): ", $RoR[0][1], "\n"; # 3(a)
print "3(b): ", $$RoR[0][1], "\n"; # 3(b)
print "4: ", $RoR->[0][1], "\n"; # 4
print "5: ", $AwR[1][0][1], "\n"; # 5
print "6: ", $AwR[1]->[0][1], "\n"; # 6
print "7: ", $AwR[1][1]->[1], "\n"; # 7
print "8: ", @{$RoR}[1]->[1], "\n"; # 8
print "9: ", @{$AwR[1]}[1]->[1], "\n"; # 9
说明: -
5
arrow
的情况下访问引用的匿名数组的索引。 3(b)有效,因为现在我们已使用reference - $RoR
$$RoR
第四个打印语句类似于3(b)
,是明确表达3(b)
正在做的事情的方法。由于RoR
是对匿名数组的引用,因此我们无法访问普通数组之类的元素。我们必须使用箭头(->
)。在arrow
之后,我们可以将索引添加到任何级别以访问嵌套的anonymous
数组。
$$RoR[0][1]
有效,因为$RoR
与左侧的去引用者$
绑定得更紧密,而不是右侧的subscript
运算符。因此,首先取消引用$RoR
以获取数组,然后应用subscript
。
以下是 Perl文档的引用: -
Perl对其五个前缀的优先规则 解除引用者(看起来像是某人发誓:$ @ *%&amp;)制作它们 绑定比后缀下标括号或大括号更紧密 Perl中看似等价的构造,$$ aref [$ i]首先执行 $ aref的deref,使得$ aref作为对数组的引用,并且 然后取消引用,最后告诉你我的价值 $ AoA指向的数组
第5和第6印刷声明与3(b)类似。由于$AwR[1]
仅包含引用$RoR
。因此,$AwR[1]
会转换为:$$RoR
。因此,$AwR[1][0][1]
与第5个陈述中的$$RoR[0][1]
类似。第6条声明: - $AwR[1]->[0][1]
转换为: - $$RoR->[0][1]
。现在这是我的疑问。 6th
语句如何工作。为什么我们可以在an arrow
上使用de-referenced reference
。
在7th
打印语句中,$AwR[1][1]->[1]
与${$RoR}[1]->[1]
类似。因此,很明显,取消引用是在下标运算符之前完成的。因此,我们可以访问2nd
引用de-referencing
后获得的数组上的$RoR
元素。
8th
和9th
print语句非常相似。还有,我们正在取消引用reference $RoR
。但现在,我们de-referencing
为array
而不是scalar
。
我试图以最好的方式解释。如果上述说明中有错误或缺少某些内容,请指出。这将有助于我了解更多信息。
此外,有人可以解释5th
和6th
打印声明。我将这个添加到上面的问题中。