我有一个关于通过引用Perl中的子例程的问题。对于值,如果我使用@_传递它可以工作但是对于ref只有shift工作。不知道为什么。我有以下给出的示例代码:
这有效:
#! /usr/bin/perl
use strict;
use warnings;
my $name = 'John';
PassScalarByRef( \$name );
sub PassScalarByRef{
my $got = shift;
print "Hello $$got\n";
}
但不是这一个:
#! /usr/bin/perl
use strict;
use warnings;
my $name = 'John';
PassScalarByRef( \$name );
sub PassScalarByRef{
my $got = @_;
print "Hello $$got\n";
}
答案 0 :(得分:13)
在第二种情况下,分配给$got
会为@_
提供标量上下文,从而使其评估其大小(元素数量)。你可以说:
my ($got) = @_;
...按照您的预期将@_
的第一个元素分配给$got
。
答案 1 :(得分:6)
您在标量上下文中使用@_
数组。 $got
现在包含传递的参数数量。您应该尝试my ($got) = @_
,现在使用列表上下文中的数组,这就是您的意思。
答案 2 :(得分:3)
大多数操作员以一致的方式为其操作数提供特定的上下文;例如,+
给出了它的操作数标量上下文; ||
给出了左操作数标量上下文及其右操作数||
本身具有的任何上下文。
分配略有不同,因为有两种类型,列表赋值和标量赋值。
标量分配如下:
$scalar = ...
lvaluesub() = ...
(lvalue subs是perl的一个很少使用的特性;内置pos
就是一个例子。)
只分配了一个值,这些值赋予=
右操作数标量上下文。
列表分配如下所示:
@array = ...
@arraytoslice[...] = ...
%hash = ...
@hashtoslice{...} = ...
( ... ) = ...
甚至
() = ...
所有这些都需要一个要分配的值列表,因此请给出正确的操作数列表上下文。
当你说:
my $got = @_;
这是一个标量赋值,因此@_
得到标量上下文,这会导致它返回元素数,而不是第一个值。
相反,请说:
my ($got) = @_;
有些人持续这样做,即使是只有一个操作数的潜艇;其他人
my $param1 = shift;
my $param2 = shift;
用于具有少量操作数的subs。
使用shift获取对象/类的方法和来自@_的列表赋值对于其余参数来说很常见。
答案 3 :(得分:0)
使用不同。
我的$ got = $ _ [0];