Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
理解perl中的数据结构_Perl - Fatal编程技术网

理解perl中的数据结构

理解perl中的数据结构,perl,Perl,我试图理解perldsc文档中的“常见错误”部分。当作者提到: 在构建类似数组的数组时,最常见的两个错误是:要么意外地计算元素的数量,要么重复引用同一内存位置。在这种情况下,只需获取计数而不是嵌套数组: #!/usr/bin/perl -w use strict; use Data::Dumper; my @count; my @new_array; for my $i (1..10) { #my @count; my @array = somefu

我试图理解perldsc文档中的“常见错误”部分。当作者提到:

在构建类似数组的数组时,最常见的两个错误是:要么意外地计算元素的数量,要么重复引用同一内存位置。在这种情况下,只需获取计数而不是嵌套数组:

#!/usr/bin/perl -w
use strict;
use Data::Dumper;
my @count;
my @new_array;

for my $i (1..10) {
           #my @count;
           my @array = somefunc($i);
           push @new_array, [@array];
       }


sub somefunc  {
my $a = shift;
return $a * $a;
}

print Dumper(\@new_array);
据我所知,当它迭代时,它将取(1..10)的第一个值,即1,并将其传递给如下函数:

my @array = somefunc(1);
#!/usr/bin/perl -w
use strict;
use Data::Dumper;

for my $i (1..10) {
           my @count;
           my @array = somefunc($i);
           print "The array is Dumper(@array)\n";
           $count[$i] = scalar @array;      
           print Dumper($count[$i]);
       }


sub somefunc  {
my $a = shift;
return $a * $a;
}
由于该函数没有定义,我将创建逻辑

sub somefunc  {
my $a = shift;
print $a * $a;
}
这基本上可以做到:

1 * 1
结果是“1”

据我所知,我的@array将如下所示:

@array = ('1');
下一行可以:

$AoA[$i] = @array;
我假设$AoA[$1]是一个匿名数组(顺便说一句,他/她并没有用“我的”声明),并且@array将是这个匿名数组的第一个元素,作者说它“错了”。以及迭代到“2”的for each循环

somefunc(2);
将成为“4”并传递给:

$AoA[$i] = @array
作者对这段错误代码的看法是什么。我试图理解什么是错误的,但更重要的是,我试图理解代码。任何帮助都将不胜感激

更新

我想我理解为什么这是一个常见的错误,因为当我使用print和Dumper时,我可以直观地看到作者试图表达的内容,下面是修改后的代码

#!/usr/bin/perl -w
use strict;
use Data::Dumper;

for my $i (1..10) {
           my @AoA;
           my @array = somefunc($i);
           print "The array is Dumper(@array)\n";
           $AoA[$i] = @array;      # WRONG!
           print Dumper($AoA[$i]);
       }


sub somefunc  {
my $a = shift;
return $a * $a;
}
在perldoc perldsc的“常见错误”一段中,他/她指出

在这种情况下,只需获取计数而不是嵌套数组:

#!/usr/bin/perl -w
use strict;
use Data::Dumper;
my @count;
my @new_array;

for my $i (1..10) {
           #my @count;
           my @array = somefunc($i);
           push @new_array, [@array];
       }


sub somefunc  {
my $a = shift;
return $a * $a;
}

print Dumper(\@new_array);
下面是转储程序的输出

The array is Dumper(1)
$VAR1 = 1;
The array is Dumper(4)
$VAR1 = 1;
The array is Dumper(9)
$VAR1 = 1;
The array is Dumper(16)
$VAR1 = 1;
The array is Dumper(25)
$VAR1 = 1;
The array is Dumper(36)
$VAR1 = 1;
The array is Dumper(49)
$VAR1 = 1;
The array is Dumper(64)
$VAR1 = 1;
The array is Dumper(81)
$VAR1 = 1;
The array is Dumper(100)
$VAR1 = 1;
所以我假设

$VAR1 = 1;
是计数,而不是嵌套数组

作者确实指出,如果计数是我真正想要的,那么重写代码如下:

my @array = somefunc(1);
#!/usr/bin/perl -w
use strict;
use Data::Dumper;

for my $i (1..10) {
           my @count;
           my @array = somefunc($i);
           print "The array is Dumper(@array)\n";
           $count[$i] = scalar @array;      
           print Dumper($count[$i]);
       }


sub somefunc  {
my $a = shift;
return $a * $a;
}

但是文档没有告诉我如何获取嵌套数组

更新

如果我错了,请更正,但我重写了代码以获取嵌套数组:

#!/usr/bin/perl -w
use strict;
use Data::Dumper;
my @count;
my @new_array;

for my $i (1..10) {
           #my @count;
           my @array = somefunc($i);
           push @new_array, [@array];
       }


sub somefunc  {
my $a = shift;
return $a * $a;
}

print Dumper(\@new_array);
哪个印刷品

$VAR1 = [
      [
        1
      ],
      [
        4
      ],
      [
        9
      ],
      [
        16
      ],
      [
        25
      ],
      [
        36
      ],
      [
        49
      ],
      [
        64
      ],
      [
        81
      ],
      [
        100
      ]
    ];

在以下声明中:

$AoA[$i] = @array;
@array
在标量上下文中被引用,从而产生许多元素。上下文由LHS施加,即
$AoA[$i]
,它是
@AoA
数组的单个元素

在Perl中,没有严格意义上的数组数组。这些基本上是通过“展平”数组或带引用的数组来模拟的。对于后者,您需要使用take reference运算符,如中所示:

$AoA[$i] = \@array;

对于初学者,您可能会发现,这在检查复杂的数据结构(如arrayrefs和hashrefs)时非常方便。

Perl是多态的,这意味着它可以透明地处理不同的数据类型,并且通常可以很好地猜测如何处理某些数据。这使得程序员的工作更加容易,因为它不像其他语言那样是强类型的

例如,如果$i是数字4,您可以这样做:

print $i + 1;
你会看到一个5-非常符合逻辑,对吗

如果你这样做:

print "I am " , $i , " years old";

您将看到“我4岁了”——在本例中,perl表示“您在列表上下文中操作,因此我将$I视为字符串。无需像许多其他语言所坚持的那样将数字转换为字符串

所以当你分配

$AoA[$i] = @array;
其处理方式取决于上下文。在标量上下文中,它将$AoA[$i]设置为数组的长度

有关标量与列表上下文的更多信息,请阅读以下答案:


您的示例对于理解这里发生的事情不是很有用,因为您的子例程总是返回“1”-调用
print()
的结果。如果将
print()
替换为
return()
,那么您将得到不同的值(1、4、9等)

但下一行代码:

$AoA[$i] = @array;
将始终将
1
分配给
@Aoa
的元素。这是因为您正在将数组(
@array
)分配给标量变量(
$Aoa[$i]
),并且当您在标量上下文中计算数组时,会得到数组中的元素数

现在,由于您的
@array
只有一个元素,您可以执行以下操作:

$AoA[$i] = $array[0];
但这并不是真正构建一个数组数组,你真正想做的是获取一个数组的引用

$AoA[$i] = \@array;
如果子例程返回多个值,这将更有用

sub somefunc  {
  # Used $x instead of $a as $a has a special meaning in Perl
  my $x = shift;
  return ($x * $x, $x * $x * $x);
}

for my $i (1..10) {
  my @array = somefunc($i);
  $AoA[$i] = \@array;
}
探索这一点的有用工具是。请尝试添加:

use Data::Dumper;
到代码的顶部,然后:

print Dumper @AoA;

foreach
循环之后,查看您返回的不同数据结构。

我认为应该是
返回$a*$a
,而不是
打印$a*$a
$AoA[$I]
引用常规数组
@AoA
$I
第个元素(作者未声明)。赋值
$AoA[$i]=@array
在标量上下文中,所以
@array
将计算为arrayRe的长度“@array将是此匿名数组的第一个元素“,否,
@array
在标量上下文中计算为
@array
中的元素数。请注意,该示例试图演示如何将
@array
放置在
@AoA
的元素中,因此
sub somefunc{my$i=shift;return($i*2,$i*3);}
将是一个更好的示例。“文档没有告诉我如何获取嵌套数组”。但我们的许多答案都告诉了我。
$AoA[$i]=\@array;
。使用转储程序打印
@AoA
,看看你得到了什么。很好,在javascript中花费的时间太多了。应该使用“.”运算符,但随后它显式地执行串联:)“你正在列表上下文中操作,因此,我将把$I视为一个字符串”。列表上下文没有说明值是被视为数字还是字符串。将其所有参数转换为字符串的是
print()
。如果将逗号替换为点,则
$I
将无效