Perl-尝试访问foreach循环中数组中的两位数时出错

Perl-尝试访问foreach循环中数组中的两位数时出错,perl,foreach,Perl,Foreach,我刚开始学习Perl,却偶然发现一个错误,我无法通过谷歌搜索或阅读我正在学习的书来解决 我的代码如下所示: for my $idx (0..$#array) { # 0, 1, 2 print "$idx\n"; } for my $element (@array) { # 1, 2, 10 print "$element\n"; } 使用严格; 使用警告; my@array=(1,2,10); foreach my$i(@array){ 打印$array[$

我刚开始学习Perl,却偶然发现一个错误,我无法通过谷歌搜索或阅读我正在学习的书来解决

我的代码如下所示:

for my $idx (0..$#array) {
    # 0, 1, 2
    print "$idx\n";
}
for my $element (@array) {
    # 1, 2, 10
    print "$element\n";
}
使用严格;
使用警告;
my@array=(1,2,10);
foreach my$i(@array){
打印$array[$i-1];
}
如果我有一个仅由一位数组成的数组,那么这个方法很有效。一旦foreach循环达到一个两位数(在本例中为10),我就会收到一条警告:“在…中使用未初始化的值”,循环停止。如果我尝试对数字做任何事情(加法等),同样的情况也会发生,它在使用单位数时效果很好,但在使用双位数时停止

我现在很难理解这里发生了什么——我想这与Perl存储数组元素的方式有关,但我找不到任何东西,也不知道要搜索什么


有人能给我指出正确的方向吗?

在Perl
foreach
中,您可以直接从迭代变量访问每个元素,在您的例子中,它是
$i

请尝试以下操作:

#!/usr/bin/perl

use strict;
use warnings;

my @array = (1, 2, 10);

foreach my $i (@array) {
    print $i."\n";
}

注意打印函数调用中的
“\n”
。不需要它,我添加它只是为了美化输出。

我不确定您想做什么,但这并没有达到您认为的效果

my @array = (1, 2, 10);
foreach my $i (@array) {
    print $array[$i-1];
}
$i
不是像0、1、2、3那样的索引。。。相反,
$i
@数组的每个元素:1、2、10。因此,
$array[$i-1]
$array[0]
$array[1]
$array[9]
@array
没有第九个元素

如果要循环遍历
@array
的每个索引,请如下循环:

for my $idx (0..$#array) {
    # 0, 1, 2
    print "$idx\n";
}
for my $element (@array) {
    # 1, 2, 10
    print "$element\n";
}
如果要循环遍历
@array
的每个元素,请按如下方式循环:

for my $idx (0..$#array) {
    # 0, 1, 2
    print "$idx\n";
}
for my $element (@array) {
    # 1, 2, 10
    print "$element\n";
}

前面的两个答案都很好。我只想在混合物中再加一点变化

#!/usr/bin/perl

use strict;
use warnings;

my @array = (6, 1, 2, 10);
my $numelements = @array;

for (my $i=0; $i < $numelements; $i++) {
    print "$array[$i]\n";
}
#/usr/bin/perl
严格使用;
使用警告;
my@array=(6,1,2,10);
我的$numelements=@array;
对于(我的$i=0;$i<$numelements;$i++){
打印“$array[$i]\n”;
}

在您阅读一本书时,我建议您也使用优秀的。下面是一些答案的例子。同时,我也会建议一些其他的细节

foreach循环迭代正常列表值,并将标量变量VAR依次设置为列表的每个元素

因此,它从数组中选取每个元素

use warnings;
use strict;
use feature 'say';

my @words = qw(one two three);

foreach my $word (@words) {
    say $word;
}
内置与打印类似,但添加了换行符,请参见。构建分配给数组
@words
的“单词”(用空格分隔)列表。它通常非常方便

如果您只想打印一个数组,那么

say for @array;
这还利用了,这是Perl中许多东西的默认设置。因此,上面的内容与@array的
相同,比如说$

如果您希望迭代数组索引,那么可以使用

其中,
$#array
@array
最后一个元素的下标(索引)的一种特殊符号。在下面找到它。在
foreach
循环中使用range时,不会生成临时数组,因此内存效率较高。虽然它也可以用来制作数组,
my@nums=1..10



问题中的代码迭代元素,然后使用它们索引到数组中。因此,它会打印$array[$element]
。只有当元素恰好是数字,并且恰好是该特定数组的有效索引时,才会意外地运行

我想提一下
每个功能。您现在可能认为必须在迭代数组索引和数组值之间进行选择:

迭代索引:

foreach my $index (0 .. $#array) {
    print "$index\n"; # 0, 1, 2
}
foreach my $value (@array) {
    print "$value\n"; # 1, 2, 10
}
迭代值:

foreach my $index (0 .. $#array) {
    print "$index\n"; # 0, 1, 2
}
foreach my $value (@array) {
    print "$value\n"; # 1, 2, 10
}
但是如果您至少有Perl5.12,那么您可以同时拥有。使用以下功能:

while (my ($index, $value) = each @array) {
    print "index=$index, value=$value\n";
}
输出:

index=0, value=1
index=1, value=2
index=2, value=10

例如,如果您想迭代数组并检查上一个或下一个元素,这将非常有用。

谢谢大家!我的错误是错误地使用了foreach循环——我将对此进行进一步的研究。太糟糕了,我不能选择多个答案作为正确答案。或者,
对于我的$idx(keys@array)
虽然这可以工作,但在Perl中通常避免使用3 arg for循环。它的速度较慢,更难阅读,并且会引起bug。仅当迭代数组或范围无效时才使用它
$num_元素
是不必要的,
$i<@array
更直接。只是为了展示另一种剥猫皮的方法。同时,给出了一个如何获取数组中元素数的示例。请注意,
foreach my$index(0..$#array)
不构建列表,如果
@array
很大,则可能会消耗大量内存。相反,它迭代该范围的每个值,因此它的内存效率相当高。我相信只有
foreach
具有这种范围操作符的优化
@a=(1..5)
仍然会生成一个列表。@Schwern啊!很好,我不知道。编辑,谢谢:)。