为什么传球需要shift而不是@_

  • 本文关键字:shift perl
  • 更新时间 :
  • 英文 :


我有一个关于在Perl中通过引用传递子例程的问题。对于值,如果我使用@_传递它工作,但对于ref只有shift工作。不知道为什么。我已经给出了下面的示例代码:

如此:

#! /usr/bin/perl
use strict;
use warnings;
my $name = 'John';
PassScalarByRef( $name );
sub PassScalarByRef{
    my $got = shift;
    print "Hello $$gotn";
}

但不是这个

#! /usr/bin/perl
use strict;
use warnings;
my $name = 'John';
PassScalarByRef( $name );
sub PassScalarByRef{
    my $got = @_;
    print "Hello $$gotn";
}

在第二种情况下,给$got赋值为@_提供了一个标量上下文,这导致它的计算值为它的大小(元素数)。你可以说:

my ($got) = @_;

…将@_的第一个元素赋值给$got,如您所愿。

您正在标量上下文中使用@_数组。$got现在包含了传递的参数数量。您应该尝试my ($got) = @_,它现在在列表上下文中使用数组,这就是您的意思。

大多数操作符以一致的方式为其操作数提供特定的上下文;例如,+给出了它的两个操作数标量上下文;||将其左操作数指定为标量上下文,而将其右操作数指定为||本身的上下文。

赋值操作略有不同,因为有两种类型:列表赋值和标量赋值。

标量赋值如下:

$scalar = ...
lvaluesub() = ...

(左值子是perl很少使用的特性;内置的pos是一个例子)。

只有一个值被赋值,这给了=的右操作数标量上下文。

List的赋值是这样的:

@array = ...
@arraytoslice[...] = ...
%hash = ...
@hashtoslice{...} = ...
( ... ) = ...

或者

() = ...

所有这些都需要赋值的值列表,因此给出正确的操作数列表上下文。

当你说:

my $got = @_;

这是一个标量赋值,所以@_得到标量上下文,这导致它返回它的元素数,而不是第一个值。

相反,说:

my ($got) = @_;

有些人一直这样做,即使对于只有一个操作数的sub;别人做

my $param1 = shift;
my $param2 = shift;

用于具有少量操作数的子节点。

方法通常使用shift和@_对其余参数赋值列表来获取对象/类。

用法不同

my $got = $_[0];

最新更新