在Perl子例程中使用@_时获取错误的参数值

mor*_*gen 3 perl arguments subroutine

我在使用@_将单个参数传递给Perl子例程时遇到了一个奇怪的错误.传入子程序的值在进入子程序后立即更改.

代码示例:

my $my_def = 0;
print "my_def = $my_def \n";
@someResult = doSomething($my_def);

sub doSomething {
    my $def = @_;
    print "def = $def \n";
    ...
}
Run Code Online (Sandbox Code Playgroud)

这返回:

> my_def = 0
> def = 1  # instead of "0"
Run Code Online (Sandbox Code Playgroud)

另一个奇怪的事情是代码在几个月前正常工作.

当我将其更改为:

sub doSomething {
    my $def = $_[0];
Run Code Online (Sandbox Code Playgroud)

谁能说出什么可能导致问题?使用@_传递单个参数是否有任何限制?

谢谢!

Jon*_*ler 13

你得到了正确的行为,虽然它不是你所期望的.

从子例程中的参数获取局部变量的简单经验法则是始终在my (...)声明中的变量列表周围使用括号:

sub do_something
{
    my ($def) = @_;
    ...
}
Run Code Online (Sandbox Code Playgroud)

不同之处在于列表上下文和标量上下文之间.在标量上下文中,所有数组都返回数组中的元素数:在您的情况下为1.当你写作时,my $def = @_你提供了标量上下文.当您使用时,my $def = $_[0]您显式访问了数组的元素零,这是一个标量(因此是$sigil)所以它再次起作用.

在一般情况下,您可能有:

sub do_something_else
{
    my ($arg1, $arg2, $arg3, @the_rest) = @_;
    ...
}
Run Code Online (Sandbox Code Playgroud)

现在,你有三个标局部变量$arg1,$arg2$arg3,和一个阵列,@the_rest收集传递任何额外的参数.