在Perl中,当我使用@_ [0],@ _ [1]等来访问子例程的参数时,为什么会收到警告?

时间:2013-04-15 10:29:43

标签: perl warnings

下面的代码。

sub max 
    {
        if (@_[0] > @_[1]) 
        {
            @_[0];
        }
        else
        {
            @_[1];
        }
    }
    print "biggest is ".&max(37,25);

当我跑步时,我收到了以下警告,

Scalar values @_[0] better written as $_[0] at file.pl line 3.
Scalar values @_[1] better written as $_[1] at file.pl line 3.
Scalar values @_[0] better written as $_[0] at file.pl line 5.
Scalar values @_[0] better written as $_[0] at file.pl line 9.
biggest is 37.

虽然我得到了正确的输出,但我想知道这个警告背后的原因是什么,因为我认为在子程序中使用@_$_更合适。

3 个答案:

答案 0 :(得分:25)

问题是您使用数组切片而不是标量来引用单个数组元素。就像错误说的那样。数组切片是数组中元素的列表,例如:

my @a = (0 .. 9);
print @a[0,3,4];    # prints 034

相反,当您引用单个数组元素时,使用标量前缀$

print $a[3];        # prints 3

所以当你这样做时

@_[0];

Perl告诉你,引用标量值的正确方法是不使用数组切片,而是使用标量符号:

$_[0];

就是这样。

答案 1 :(得分:3)

尝试用这个例子来理解它:

@array = (1,2,3); #array is the name of the array and @ means that it's an array
print $array[1];  
#this will print element at index 1 and you're doing it in scalar context

类似地,

@_ = (1,2,3); #_ is the name of the array
print $_[1]; 
#this will print element at index 1 of array _ and again you're doing it in scalar context

答案 2 :(得分:1)

您指的是数组,而不是标量。 @_[0]表示($_[0])。但是perl有点clever所以它警告你,你应该返回一个标量,而不是一个明确的单个元素列表。在这里您应该使用$_[0]

我建议您使用原型,因为现在您可以调用max (1, 2, 3),结果将是2,而不是3。所以定义为

sub max ($$) { $_[0] > $_[1]) ? $_[0] : $_[1] }

或者更好,您可以使用未定义的数字(> = 2)元素。用0或1项称它可能毫无意义。

sub max (@) { 
    return undef if $#_<0; 
    my $s = shift; 
    for(@_) { $s = $_ if $_ > $s } $s 
}