Perl中foreach循环遍历数组的机制及循环次数异常咨询
为什么你的Perl foreach循环只执行2次?
这是个很典型的Perl循环陷阱——问题出在你在foreach循环内部修改了正在遍历的数组,而Perl的foreach迭代行为和你预想的不太一样。我来一步步拆解清楚:
先搞懂Perl foreach的核心工作机制
Perl里的foreach(和for是等价写法)循环,并不会先把数组元素做一个"快照"再遍历固定列表。相反,它会直接绑定到原数组的元素,并且每次迭代都会参考当前数组的长度来判断是否继续循环。
更直白地说:
- 循环启动时,Perl会初始化一个迭代器,从数组的第0个元素开始遍历
- 每完成一次循环,迭代器的索引就+1
- 当索引值等于当前数组的长度时,循环会立刻终止
逐行分析你的代码执行过程
我们把你的代码一步步走一遍,就能明白为什么只执行了2次:
初始状态:@arr = ("sandeepr", "vijay","vikas")(数组长度为3)
第一次循环
$i被赋值为数组第0个元素:"sandeepr"- 执行
print @arr,输出sandeeprvijayvikas - 执行
pop(@arr),数组最后一个元素"vikas"被移除,此时@arr变成("sandeepr", "vijay")(长度变为2) - 打印
$b的值:vikas
第二次循环
- 迭代器索引+1,变成1,此时数组长度是2,索引1小于2,继续循环
$i被赋值为数组第1个元素:"vijay"- 执行
print @arr,输出sandeeprvijay - 执行
pop(@arr),数组最后一个元素"vijay"被移除,此时@arr变成("sandeepr")(长度变为1) - 打印
$b的值:vijay
为什么没有第三次循环?
- 迭代器索引继续+1,变成2,此时数组长度已经是1,索引2 >= 1,循环直接终止!所以根本不会进入第三次循环。
解决方法:遍历原数组的快照
如果你想遍历原数组的所有3个元素,同时又要修改原数组(比如执行pop操作),你需要先把原数组的元素复制到一个临时列表里,遍历临时列表而非原数组:
#!/usr/bin/perl use strict; use warnings; my @arr=("sandeepr", "vijay","vikas"); # 复制原数组到临时列表,基于快照遍历 my @original_elements = @arr; for my $i( @original_elements ) { print @arr; my $b=pop(@arr); print "\n $b"; }
这样循环会基于原数组的初始长度(3次)执行,即使你修改原数组,也不会影响循环的次数。
内容的提问来源于stack exchange,提问作者rawatsandeep1989
相关产品推荐
相关产品推荐

