参考:https://perl-book.junmajinlong.com/ch3/5_iterator.html
指针遍历:
while循环或for循环遍历列表时可以获得各元素的索引
可以使用while循环或for循环的方式来遍历所有元素:
my @arr = qw(a b c d e f);
# while
my $i = 0;
while($i <= $#arr){
say "index: $i, value: $arr[$i]";
$i++;
}
# for
for(my $i=0;$i<=$#arr;$i++){
say "index: $i, value: $arr[$i]";
}
上面的while和for循环利用的是数组的最大索引$#arr
,使用数组的长度作为条件也一样。
for迭代或foreach迭代列表各元素时,无法获取迭代时元素的索引
一般来说,使用迭代的方式来遍历数组或遍历列表会更方便。Perl中可以使用for或foreach进行迭代,foreach是for的语法糖,foreach能做的,for都能做。
for或foreach的迭代数组或列表的方式如下。
my @arr = qw(a b c d e f);
# for
for my $v (@arr) {
say "value: $v";
}
# foreach
foreach my $v (@arr) {
say "value: $v";
}
for或foreach迭代时,会从列表中逐个取元素,取一个元素,赋值给迭代控制变量$v
,然后执行一次循环体,再继续取下一个元素。
注意,迭代每个列表元素时,元素是按引用传递给控制变量的,控制变量在栈中保存了元素的内存地址,每次迭代时控制变量的地址都发生改变。因此可以推断,每次迭代时,Perl都会重新声明控制变量,每次声明的控制变量仅在本次迭代过程中有效。
my @arr = (11, 22, 33, 44);
my $v = 3333;
say \$v;
say '---- before ----';
for my $v (@arr) { say \$v; }
say '---- after ----';
say \$v;
say "$v";
# 输出:
# SCALAR(0x22f3d10)
# ---- before ----
# SCALAR(0x2277ab0)
# SCALAR(0x2277a98)
# SCALAR(0x2277b40)
# SCALAR(0x2277b58)
# ---- after ----
# SCALAR(0x22f3d10)
# 3333
因此,for或foreach迭代时,赋值过程大致如下图:
因此,如果在循环体内修改控制变量,也将直接修改列表中该元素的值。
my @arr = (11, 22, 33, 44);
for my $v (@arr) {
$v++;
}
say "@arr"; # 输出:12 23 34 45
在使用for/foreach迭代数组时要注意,修改数组大小会影响迭代。
my @arr = (11,22,33,44,55,66);
for my $i (@arr){
shift @arr;
say $i; # 11 33 55
}
默认标量变量$_
for和foreach迭代时需指定控制变量,例如for $i (...)
。
控制变量是可以省略的,此时将使用Perl的默认标量变量$_
。
下面两条for迭代语句完全等价:
for(11,22,33){ say $_; }
for $_ (11,22,33) { say $_; }
Perl的很多操作都允许省略操作目标,此时将使用默认变量$_
作为这些操作的操作目标。以后在使用Perl的过程中,自然会发现这一点。
没有评论:
发表评论