The special array, @_
, where all the arguments passed to a function are present, is actually an alias to the arguments passed. Hence, any change we make directly to this special array @_
will reflect in the main as well. This is clear.
特殊数组@_,其中传递给函数的所有参数都存在,实际上是传递的参数的别名。因此,我们直接对这个特殊数组@_进行的任何更改都将反映在主要数组中。这很清楚。
#!/usr/bin/perl
use warnings;
use strict;
$\="\n";
sub func {
print \@_;
$_++ for(@_);
}
my @arr=(2..4);
print \@arr;
func(@arr);
print "@arr";
For the above program, I expected the reference of @arr
and @_
to point to the same location since it is an alias. But it is not so.
对于上面的程序,我希望@arr和@_的引用指向同一个位置,因为它是别名。但事实并非如此。
On running the above:
在运行上面:
ARRAY(0x1b644d0)
ARRAY(0x1b644e0)
3 4 5
If they are pointing to 2 different locations, how the changes done in @_
is reflecting in @arr
?
如果他们指向2个不同的位置,@ _中的更改如何反映在@arr中?
Am I seeing something wrong? Please advice.
我看到了什么问题吗?请指教。
2 个解决方案
#1
17
This might answer you question:
这可能会回答你的问题:
use warnings;
use strict;
$\="\n";
sub func {
print \@_;
$_++ for(@_);
print \$_ for @_;
}
my @arr=(2..4);
print \@arr;
func(@arr);
print "@arr";
print \$_ for @arr;
Output
产量
ARRAY(0x17fcba0)
ARRAY(0x1824288)
SCALAR(0x17fcc48)
SCALAR(0x18196f8)
SCALAR(0x1819710)
3 4 5
SCALAR(0x17fcc48)
SCALAR(0x18196f8)
SCALAR(0x1819710)
As you see, individual arguments have the same address but the container is not the same. If you push an item to @_
in func
the @arr
will not change (so you can do shift
in funct
). So, each argument is an alias and array elements are passed as individual items. @_
contains all items passed into the subroutine. If you want to modify an array argument you need to pass it by reference.
如您所见,各个参数具有相同的地址,但容器不相同。如果你在func中将一个项目推送到@_,则@arr不会改变(所以你可以做功能转移)。因此,每个参数都是别名,数组元素作为单独的项传递。 @_包含传递到子例程的所有项。如果要修改数组参数,则需要通过引用传递它。
#2
11
@_
isn't aliased; its elements are.
@_没有别名;它的元素是。
Remember that
记住这一点
func(@arr);
is the same as
是相同的
func($arr[0], $arr[1], ...);
because the only thing that can be passed to a sub is a list of scalars, and an array evaluates to a list of its elements in list context.
因为唯一可以传递给sub的是标量列表,并且数组在列表上下文中计算其元素列表。
So that means
这意味着
func(@arr);
is basically the same as
基本上是一样的
local @_;
alias $_[0] = $arr[0];
alias $_[1] = $arr[1];
...
&func;
Changing the elements of @_
will change elements of @arr
, but adding and removing elements of @_
won't change @arr
since they are different arrays.
更改@_的元素将更改@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
#1
17
This might answer you question:
这可能会回答你的问题:
use warnings;
use strict;
$\="\n";
sub func {
print \@_;
$_++ for(@_);
print \$_ for @_;
}
my @arr=(2..4);
print \@arr;
func(@arr);
print "@arr";
print \$_ for @arr;
Output
产量
ARRAY(0x17fcba0)
ARRAY(0x1824288)
SCALAR(0x17fcc48)
SCALAR(0x18196f8)
SCALAR(0x1819710)
3 4 5
SCALAR(0x17fcc48)
SCALAR(0x18196f8)
SCALAR(0x1819710)
As you see, individual arguments have the same address but the container is not the same. If you push an item to @_
in func
the @arr
will not change (so you can do shift
in funct
). So, each argument is an alias and array elements are passed as individual items. @_
contains all items passed into the subroutine. If you want to modify an array argument you need to pass it by reference.
如您所见,各个参数具有相同的地址,但容器不相同。如果你在func中将一个项目推送到@_,则@arr不会改变(所以你可以做功能转移)。因此,每个参数都是别名,数组元素作为单独的项传递。 @_包含传递到子例程的所有项。如果要修改数组参数,则需要通过引用传递它。
#2
11
@_
isn't aliased; its elements are.
@_没有别名;它的元素是。
Remember that
记住这一点
func(@arr);
is the same as
是相同的
func($arr[0], $arr[1], ...);
because the only thing that can be passed to a sub is a list of scalars, and an array evaluates to a list of its elements in list context.
因为唯一可以传递给sub的是标量列表,并且数组在列表上下文中计算其元素列表。
So that means
这意味着
func(@arr);
is basically the same as
基本上是一样的
local @_;
alias $_[0] = $arr[0];
alias $_[1] = $arr[1];
...
&func;
Changing the elements of @_
will change elements of @arr
, but adding and removing elements of @_
won't change @arr
since they are different arrays.
更改@_的元素将更改@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