在Perl中传递标量引用

时间:2011-05-03 15:14:31

标签: perl reference arguments scalar

我知道将标量传递给sub实际上是通过引用,但由于我是perl的新手,我仍然进行了以下测试:

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

我认为第一行将打印一个地址,第二行将返回该数字,但第二行是一个空行。我被其他人指出要执行此操作:${$_[0]}并打印数字。但她不知道为什么没有{}它不起作用以及为什么它与{}合作。那发生了什么事?

4 个答案:

答案 0 :(得分:14)

这是因为你的第二个印刷声明等同于这样做......

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

当你想要的是什么

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

换句话说,取消引用发生在评估数组下标之前。

当你添加那些curl-wurlies时,它告诉perl如何解释你想要的表达式;它将首先评估$_[0],然后取消引用以获取值。

答案 1 :(得分:8)

这是一个评估顺序。

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

这是标量变量$ _的引用的第0个元素。它首先获取引用,然后尝试找到它的第0个元素。

  ${$_[0]}

这是对数组@_的第0个元素的引用。它首先找到第0个元素,然后参考它。

如果您在代码顶部设置use strictuse warnings,则会在第一次尝试时看到大量有关未定义值的警告。

答案 2 :(得分:3)

$$_[0]$foo[0]类似,仅使用$ _代替数组名称。这意味着$ _被视为数组引用,表达式根本不涉及标量引用$_[0]$_->[0]是等效的,使用备用->语法。解除引用的语法可能看似随意且难以记住,但存在潜在的感觉和顺序;一个非常好的演示文稿是http://perlmonks.org/?node=References+quick+reference

答案 3 :(得分: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

输出:

{{1}}