map 和 grep 是 Perl 中用于数组操作的强大函数:
my @nums = (1, 2, 3, 4, 5, 6); my @squared = map { $_ * $_ } @nums; # (1, 4, 9, 16, 25, 36) my @even = grep { $_ % 2 == 0 } @nums; # (2, 4, 6)
map 和 grep 的块内部,变量 $_ 默认包含当前元素。修改 $_ 将改变原始数组中的元素,如果数组通过引用传递或显式使用 $_(例如,通过 foreach 的别名)。map 始终返回一个列表,grep 返回原始列表的一个子集。问题: 以下代码做了什么,为什么?
my @nums = (1..5); my @result = map { $_++ } @nums; print "@nums ";
答案: 这段代码不会修改原始数组 @nums。运算符 $_++ 在块内增加了变量的值,但不会将这些更改保存到原始数组中,因为 map 返回了更改后的值,但原始数组没有受到影响(除非通过 foreach 使用别名)。
my @nums = (1..5); my @result = map { $_++ } @nums; # @result 将是 (1,2,3,4,5),@nums 不变 print "@nums "; # 输出:1 2 3 4 5
故事 在一个项目中,开发人员期待
map { $_++ } @array后,数组@array将被更改。结果,程序继续使用旧值,导致数据聚合时的错误计算。
故事 在报告系统中,在通过
grep过滤数组时,块内不小心使用了赋值命令$result = $_,导致所有元素被重写到同一个变量中,丢失了数据来源。这导致调试变得复杂,并导致报告中的损失。
故事 在集成脚本中应用了嵌套
map,并忘记内部上下文也使用了共享变量$_,这在修改元素时导致了不可预测的行为,因为内部的map覆盖了结果数组中的值。