我有一个关于在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];