使用对匿名数组的引用作为数组的元素

时间:2012-10-31 10:54:35

标签: perl

我试图以各种方式使用对数组的引用,我理解可以这样做。
这是我的一个试验: -

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},而不是使用新的匿名数组。所以,基本上我认为,最后两个数组实际上是相同的。

现在,问题是,他们的行为方式不一样

  • 打印报表12工作正常,并打印出值5作为结果。

  • 打印语句3给出错误,我知道原因,所以没问题。打印语句4正在按预期打印值3

  • 现在,当我尝试运行程序时,打印语句56会出现一些错误。

    "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 twolast 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.

那么,以两种不同的方式使用它有什么不同?

3 个答案:

答案 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
  • 3(a)将无法编译,因为我们无法在没有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元素。

  • 8th9th print语句非常相似。还有,我们正在取消引用reference $RoR。但现在,我们de-referencingarray而不是scalar


我试图以最好的方式解释。如果上述说明中有错误或缺少某些内容,请指出。这将有助于我了解更多信息。

此外,有人可以解释5th6th打印声明。我将这个添加到上面的问题中。