2011-05-03 37 views
5

傳遞一個標量引用我知道,經過一個標量子實際上是通過參考,但因爲我是新來的perl的我還是做了以下測試:在Perl

#!/usr/bin/perl 
$i = 2; 
subr(\$i); 
sub subr{ 
    print $_[0]."\n"; 
    print $$_[0]."\n"; 
} 

我認爲第一線打算打印一個地址,第二行將返回數字,但第二行是空行。我被其他人指出要做到這一點:${$_[0]},它打印的數字。但她不知道沒有工作的原因,以及爲什麼工作在{}。那麼發生了什麼?

回答

13

這是因爲你的第二個print語句等價於這樣做......

my $x = $$_; print $x[0]; 

如果你想要的是

my $x = $_[0]; print $$x; 

換句話說,解引用數組下標之前發生被評估。

當你添加這些curl-wurlies時,它會告訴perl如何根據需要解析表達式;它將首先評估$_[0],然後取消參考以獲取該值。

+0

這太好了,謝謝 – user685275 2011-05-03 16:26:45

7

這是一種評估順序。

$$_[0] is evaluated as {$$_}[0] 

這是標量變量$ _的引用的第0個元素。它先取參考,然後試圖找到它的第0個元素。

${$_[0]} 

這是對數組@_的第0個元素的引用。它首先找到第0個元素,然後參考這個。

如果您在代碼頂部設置了use strictuse warnings,您會在第一次嘗試時看到大量關於未定義值的警告。

+0

這太好了,謝謝 – user685275 2011-05-03 16:26:51

1

您不必傳遞參考$i$_[0]別名$i,當您調用它作爲subr($i)時。

use strict; 
use warnings; 
use Test::More tests => 2; 

sub subr{ $_[0]++ } # messing with exactly what was passed first 
my $i=2; 
is($i, 2, q[$i == 2]); 
subr($i); 
is($i, 3, q[$i == 3]); 

又如是這樣的:

use strict; 
use warnings; 
use Test::More tests => 6; 
use Test::Exception; 

sub subr{ $_[0]++ } 
my $i=2; 
is($i, 2, q[$i == 2]); 
subr($i); 
is($i, 3, q[$i == 3]); 

sub subr2 { $_[0] .= 'x'; } 
dies_ok { subr2('lit'); } 'subr2 *dies* trying to modify a literal'; 
lives_ok { 
    my $s = 'lit'; 
    subr2($s); 
    is($s, 'litx', q[$s eq 'litx']); 
    subr2((my $s2 = 'lit')); 
    is($s2, 'litx', q[$s2 eq 'litx']); 
} 'subr2 lives with heap variables'; 

輸出:

ok 1 - $i == 2 
ok 2 - $i == 3 
ok 3 - subr2 *dies* trying to modify a literal 
ok 4 - $s eq 'litx' 
ok 5 - $s2 eq 'litx' 
ok 6 - subr2 lives with heap variables 
1..6 
3
$$_[0]

就像$foo[0],只有$ _代替數組名。這意味着$ _被視爲數組引用,並且表達式根本不涉及標量引用$_[0]$_->[0]是等效的,使用備用->語法。解引用的語法看起來可能是任意的,難以記憶,但有潛在的意義和順序;一個非常好的介紹是在http://perlmonks.org/?node=References+quick+reference