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

时间:2022-05-31 12:17:18

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