为什么从@_移位值不是别名?

Eug*_*kov 3 perl parameter-passing subroutine

shift
将数组的第一个值移开并返回...

这样做是为了速度优化并避免按值复制.

也在perlsub

数组@_是一个本地数组,但它的元素是实际标量参数的别名.特别是,如果更新元素$ _ [0],则更新相应的参数

因此,如果我们my $self = shift在sub中执行,我们将第一个值移位@_,这是一个别名,不是吗?

但是当我们比较这两个时:

sub test {
     print \$_[0];    # SCALAR(0xf73c38)
     my $x =  shift;
     print \$x;       # SCALAR(0xf79800)
}
Run Code Online (Sandbox Code Playgroud)

我们看到那$x是副本.

为什么shift@_ 的ed值不是别名?

因此,如果也为案例复制了价值my $x = shift,它会提供什么好处my $x = $_[0]呢?

mob*_*mob 9

移位的值是别名

$ perl -E 'sub F{say \$_[0]; say \shift} $x=42; say \$x; F($x)'
SCALAR(0x1d7f1e0)
SCALAR(0x1d7f1e0)
SCALAR(0x1d7f1e0)
Run Code Online (Sandbox Code Playgroud)

赋值操作(例如,$x = $_[0]$x = shift)在右侧创建标量的副本,因此新分配的值不再是别名.

正如工具所说,改进的好处shift@_,有时可以更容易地在子程序的其余部分中使用.

如果您仍希望能够修改输入,则仍可以使用对移位值的引用

$ perl -E 'sub G { my $x=\shift; $$x = 19 } my $z = 42; G($z); say $z'
19
Run Code Online (Sandbox Code Playgroud)

  • 如果你传递不同类型的东西,那么`shift`的优势就在于此.例如:`my $ self = shift;`当面向对象时,`@ _`的其余部分是'参数'. (2认同)