2013-04-08 70 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

相關問題