2013-04-08 66 views
0

我有一个关于在Perl中通过引用子例程的问题。对于如果我通过使用@_的值,它可以工作,但仅供参考移位工作。不知道为什么。下面我已经givedn示例代码:为什么通过ref需要移位而不是@_?

这工作:

#! /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

注意:Perl总是通过*参考*。你正在做的是传递* a * ref。 – ikegami 2013-04-08 03:22:46

+0

未来人们遇到此问题时的注意事项:此问题与通过引用或按值传递完全没有关系。它与列表分配和标量分配有关。 – 2013-04-08 09:55:02

回答

13

在第二种情况下,分配给$got提供标上下文@_,这会导致它要评估它的大小(元素数量)。你可以代替说:

my ($got) = @_; 

...到@_第一要素分配给$got,如您所愿。

6

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

0

用法不同。

my $ got = $ _ [0];

3

大多数运营商以一致的方式给他们的操作数一个特定的上下文;例如,+给出了它的操作数标量上下文; ||给出了其左操作数标量上下文及其右操作数,无论||本身具有何种上下文。

赋值有点不同,因为有两种类型,列表赋值和标量赋值。

标量分配是这样的:

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

(左值潜艇都是perl的很少使用的特征;内建pos是一个例子)。

只分配了一个值,这些值给出=的右操作数标量上下文。

列表分配是这样的:

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

甚至

() = ... 

所有这些期待值分配的列表,以便给出正确的操作列表环境。

当你说:

my $got = @_; 

这是一个标量分配,因此@_得到标量上下文,这会导致它返回它的一些元素,而不是第一个值。

相反,说:

my ($got) = @_; 

有些人经常这么做,即使只有一个操作数的潜艇;其他人做

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

对于具有少量操作数的子。

对于剩下的参数来说,使用shift和@_的列表赋值来获取对象/类是很常见的。

+1

[Mini-Tutorial:标量与列表赋值运算符](http://www.perlmonks.org/?node_id=790129),我的版本。 – ikegami 2013-04-08 03:25:05

相关问题