Perl:特殊数组@_真的不是别名吗?

时间:2013-03-07 04:55:38

标签: perl

特殊数组@_,其中传递给函数的所有参数都存在,实际上是传递的参数的别名。因此,我们直接对此特殊数组@_所做的任何更改也将反映在主要数组中。这很清楚。

#!/usr/bin/perl

use warnings;
use strict;

$\="\n";

sub func {
        print \@_;
        $_++ for(@_);
}

my @arr=(2..4);
print \@arr;
func(@arr);
print "@arr";

对于上述程序,我希望@arr@_的引用指向同一位置,因为它是别名。但事实并非如此。

运行上述内容:

ARRAY(0x1b644d0)
ARRAY(0x1b644e0)
3 4 5

如果他们指向2个不同的位置,@_中所做的更改如何反映在@arr中?

我看到了什么问题吗?请指教。

2 个答案:

答案 0 :(得分:17)

这可能会回答你的问题:

use warnings;
use strict;

$\="\n";

sub func {
        print \@_;
        $_++ for(@_);
        print \$_ for @_; 
}

my @arr=(2..4);
print \@arr;
func(@arr);
print "@arr";
print \$_ for @arr;

<强>输出

ARRAY(0x17fcba0)
ARRAY(0x1824288)
SCALAR(0x17fcc48)
SCALAR(0x18196f8)
SCALAR(0x1819710)
3 4 5
SCALAR(0x17fcc48)
SCALAR(0x18196f8)
SCALAR(0x1819710)

如您所见,各个参数具有相同的地址,但容器不相同。如果您将项目推送至@_中的func@arr将不会更改(因此您可以在shift中执行funct)。因此,每个参数都是别名,数组元素作为单独的项传递。 @_包含传递到子例程的所有项。如果要修改数组参数,则需要通过引用传递它。

答案 1 :(得分:11)

@_没有别名;它的元素是。

请记住

func(@arr);

相同
func($arr[0], $arr[1], ...);

因为可以传递给sub的唯一内容是标量列表,并且数组在列表上下文中求值为其元素列表。

这意味着

func(@arr);

基本相同
local @_;
alias $_[0] = $arr[0];
alias $_[1] = $arr[1];
...
&func;

更改@_的元素会更改@arr的元素,但添加和删除@_的元素不会更改@arr,因为它们是不同的数组。

>perl -E"@a=(4..6); sub { $_[0] = '!';        say @_; }->(@a); say @a;"
!56
!56

>perl -E"@a=(4..6); sub { splice(@_,0,1,'!'); say @_; }->(@a); say @a;"
!56
456