我想知道为什么Perl有将参数通过引用传递给函数的能力?
我知道Python和Ruby都没有这样的功能。
区分一件事情和另一件事情是有用的。
(1) 通过引用将参数传递给子例程。在Perl中,这非常有用,因为语言将所有参数作为“未区分的值列表”传递给子例程。如果没有通过引用传递数据结构的能力,例如,一个函数需要获取两个列表,设计者将无法将它们区分开来。此外,如果数据结构很大,通过引用传递它们可以提高性能。
process_two_lists( @x, @y); # Can't distinguish the lists.
process_two_lists(\@x, \@y); # Can.
@_
作为传递的参数的别名,允许子例程修改调用者所感知的数据。sub add_ten_to_me {
$_[0] += 10;
}
my $x = 1;
add_ten_to_me($x);
say $x; # 11 Amazing!
Python和Ruby也可以做这种类型的事情;然而,有一些限制。Python区分可变对象和不可变对象。如果你把可变的东西(例如列表)传递给Python方法,该方法就能够修改数据结构。因此,一个Python版本的process_two_lists
将能够修改x
和y
。然而,接收不可变对象(例如整数)的函数则不能。因此,直接的Python类比add_ten_to_me
是不起作用的。(我相信Ruby也可以提出类似的观点,但我对细节了解较少。)
通过引用传递参数可以显著提高性能。
Perl 给你选择权。我认为这是 TIMTOWTDI 想法的一部分。它是一种灵活的方法,所以你可以做你需要的事情。如果你将参数作为 $_[0]
访问,则是相同的对象。如果你将它移动或复制到一个词法作用域中,则是按值传递。
因此,可以这样想。大多数代码都是按值传递的,但当你需要时,按引用方式可用。
@_
包含别名是一个意外的功能,人们早在Perl 3时代就开始依赖它了,或者可能是使用for
时。搜索p5p存档和git repo没有结果,但@tchrist或@merlyn会知道答案。 - Greg Bacon