如果我有一个已定义为字符串的变量,
my $x = "abc";
sub p { ... }
然后我必须p("$x")
还是p($x)
或p($hash->{x})
?
我的测试中都有效。没有引用的任何缺点?
答案 0 :(得分:8)
p($x)
和p($hash->{x})
没问题。当你执行
my ($x) = @_;
或
my $x = shift;
无需在来电者一方创建副本(使用"$x"
)。
如果你没有复制元素,如果更改了sub中的全局变量,你可能会遇到问题,并且你也将该全局变量作为参数传递给sub。
$ perl -E'
my $x;
sub f { $x = "def"; say $_[0] }
$x = "abc";
say $x;
f($x);
'
abc
def
但你为什么要那样做?这个似是而非的例子我可以想到以下几点:
$ perl -E'
sub f { "def" =~ /(.*)/s; say $_[0] }
"abc" =~ /(.*)/s;
say $1;
f($1);
'
abc
def
所以也许f("$1")
有时候会有意义,但那是关于它的。
答案 1 :(得分:8)
无论是否将其用作子例程调用参数,引用单个标量变量通常被认为是不好的做法,如"$s"
中所述,原因有两个
您不必要地将值重复
您可能正在调用重载的 stringify 行为
当然,第二个也可能是选择这样做的一个很好的理由,因为你想要使用stringify特殊行为。
使用裸变量作为子例程参数的唯一缺点是,由于Perl通过引用传递值,因此可以在子例程中修改该值。但是,您需要修改@_
的元素,这是非常难以做到的。
子程序的通常形式是这个
sub proc {
my ($p1, $p2, $p3) = @_;
# Do stuff with $p1, $p1, $p3
}
在这种情况下,您正在使用参数的安全副本,并且修改它们对实际参数没有影响