为什么Perl允许通过引用传递参数?

5
我想知道为什么Perl有将参数通过引用传递给函数的能力? 我知道Python和Ruby都没有这样的功能。

2
你是指隐式传递还是显式传递引用?或许可以举个例子来说明你的意思。 - TLP
为什么您想要省略通过引用传递参数的能力? - Dave Sherohman
似乎@_包含别名是一个意外的功能,人们早在Perl 3时代就开始依赖它了,或者可能是使用for时。搜索p5p存档和git repo没有结果,但@tchrist或@merlyn会知道答案。 - Greg Bacon
@TLP,我的意思是在变量前加上反斜杠“\”。 - andreypopp
@Dave Sherohman,我认为这是一种错误的编程方法——在函数调用内重新绑定外部变量名会使代码更难阅读。 - andreypopp
3个回答

7

区分一件事情和另一件事情是有用的。

(1) 通过引用将参数传递给子例程。在Perl中,这非常有用,因为语言将所有参数作为“未区分的值列表”传递给子例程。如果没有通过引用传递数据结构的能力,例如,一个函数需要获取两个列表,设计者将无法将它们区分开来。此外,如果数据结构很大,通过引用传递它们可以提高性能。

process_two_lists( @x,  @y); # Can't distinguish the lists.
process_two_lists(\@x, \@y); # Can.

因为Python和Ruby的设计不同,它们在参数传递方面不需要进行这种区分。在Python或Ruby中,类似的方法将接收两个不同的参数(代表列表的对象 x 和 y)。
Perl的行为是,@_作为传递的参数的别名,允许子例程修改调用者所感知的数据。
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将能够修改xy。然而,接收不可变对象(例如整数)的函数则不能。因此,直接的Python类比add_ten_to_me是不起作用的。(我相信Ruby也可以提出类似的观点,但我对细节了解较少。)


2
我认为#2通常被人们称为“按引用传递”。#1被称为传递一个引用。 - user102008

6

通过引用传递参数可以显著提高性能。


4

Perl 给你选择权。我认为这是 TIMTOWTDI 想法的一部分。它是一种灵活的方法,所以你可以做你需要的事情。如果你将参数作为 $_[0] 访问,则是相同的对象。如果你将它移动或复制到一个词法作用域中,则是按值传递。

因此,可以这样想。大多数代码都是按值传递的,但当你需要时,按引用方式可用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接