前几天,需要一次遍历数组的一个子集。最初,我用 splice 做到了这一点——在这种情况下撕开阵列没有问题。它会一次返回 N 个元素,或者列表末尾剩下的任何元素。一切顺利。
后来我发现我需要这个数组。我没有拼接,而是切换到数组切片。繁荣!程序爆炸了,到处都是堆栈溢出。什么?为什么?如何?我试了一下,发现了几个可行的变体。下面是演示此问题的测试脚本:
use strict;
use warnings;
my @array = qw(a b c d e f g h i j k l m n o p q r s t u v z x c v b a s d f g a s d f a se g);
my $numPerTest = 5;
my $index = 0;
print "Separating out the subset before grepping it, good.\n";
while ($index < @array)
{
print "Iteration $index\n";
my @subset = @array[$index..($index+$numPerTest)];
@subset = grep { defined $_ } @subset;
$index += $numPerTest;
}
$index = 0;
print "Making a copy of the array before grepping works.\n";
while ($index < @array)
{
print "Iteration $index\n";
my @subset = grep { defined $_ } @{[ @array[$index..($index+$numPerTest)] ]};
$index += $numPerTest;
}
$index = 0;
print "Grepping the array slice directly, explodey!\n";
while ($index < @array)
{
print "Iteration $index\n";
my @subset = grep { defined $_ } @array[$index..($index+$numPerTest)];
$index += $numPerTest;
}
(实际上,我只是想出了这个,但我想我还是把它贴出来吧。看看有没有其他人看到它。:))
(此外,如果您没有看到它,this 有另一种解释为什么会发生的方式。)
最佳答案
通过将切片用作左值,每次数组太短时您都会扩大数组。因此,它永远不会超出元素。
在前两个示例中,您仅将其用作右值,因此没有创建额外的元素。在第三个中,它是一个左值,因此创建了元素,以便可以将 $_
分配给。
这不是特定于切片的行为:在普通数组访问中显示了完全相同的行为。
关于perl - 为什么我的数组切片上的 grep 会导致 Perl 中的堆栈溢出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/566362/