特殊数组@_
,其中传递给函数的所有参数都存在,实际上是传递的参数的别名。因此,我们直接对此特殊数组@_
所做的任何更改也将反映在主要数组中。这很清楚。
#!/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
中?
我看到了什么问题吗?请指教。
答案 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