Perl子例程何时用$_传参,何时用$_[0]?
Parallel::Loops 用 $_ 接收参数的原因:调用约定差异
核心区别在于 Parallel::Loops 的 foreach 方法对传入的子引用采用了特殊的调用逻辑,完全模仿Perl原生foreach循环的行为,而非遵循普通子例程的参数传递规则:
1. 普通子例程的参数传递规则
你平时写的子例程调用(比如$a->(1))是Perl的标准行为:
- 调用时传入的参数会被打包进子例程内部的
@_数组,$_[0]就是第一个参数 $_作为默认全局变量,不会自动关联子例程的参数,除非你在子例程里手动赋值(比如$_ = $_[0])
你的测试代码结果也验证了这一点:
$a = sub { print "\$_=$_\n" ; print "\$_[0]=$_[0]\n" }; $a->(1); # 输出: # $_= # $_[0]=1
2. Parallel::Loops 的特殊调用逻辑
Parallel::Loops 的foreach方法在执行你的子引用时,并没有按标准方式把参数传入@_,而是做了两件事:
- 取出当前迭代的参数值,直接赋值给全局变量
$_ - 调用你的子引用(没有传递任何参数到
@_)
这就是为什么模块示例里必须用$_才能拿到值——模块根本没往@_里塞参数,它的设计就是让子引用像在原生foreach循环里一样工作,用$_作为默认迭代变量。你可以做个测试验证:在Parallel::Loops的子引用里打印@_,会发现输出是空的,而$_能正确拿到当前迭代值。这不是笔误,是模块刻意设计的调用约定。
内容的提问来源于stack exchange,提问作者KJ7LNW
相关产品推荐
相关产品推荐

