如前所述,for(each) 是一个急切的循环,因此它希望在开始之前评估整个列表。
为简单起见,我建议使用迭代器对象或闭包,而不是尝试使用延迟评估的数组。虽然您可以使用 tie 来获得一个惰性求值的无限列表,但如果您(直接或间接地,如上面的 foreach 中)询问整个列表(甚至整个列表的大小),您可能会遇到麻烦。
无需编写完整的类或使用任何模块,您只需使用闭包即可创建一个简单的迭代器工厂:
sub make_iterator {
my ($value, $max, $step) = @_;
return sub {
return if $value > $max; # Return undef when we overflow max.
my $current = $value;
$value += $step; # Increment value for next call.
return $current; # Return current iterator value.
};
}
然后使用它:
# All the even numbers between 0 - 100.
my $evens = make_iterator(0, 100, 2);
while (defined( my $x = $evens->() ) ) {
print "$x\n";
}
CPAN 上还有Tie::Array::Lazy模块,它为惰性数组提供了更丰富、更完整的接口。我自己没有使用过该模块,因此您的里程可能会有所不同。
祝一切顺利,
保罗