如果perl是逐个引用的,为什么会发生这种情况呢?

时间:2014-06-05 15:00:47

标签: perl pass-by-reference call-by-value evaluation-strategy

我已经读过perl在执行subrutines时使用call-by-reference。我做了一个简单的代码来检查这个属性,但它的行为就像perl是按值调用:

$x=50;
$y=70;

sub interchange {
    ($x1, $y1) = @_;

    $z1 = $x1;
    $x1 = $y1;
    $y1 = $z1;

    print "x1:$x1 y1:$y1\n";
}

&interchange ($x, $y);

print "x:$x y:$y\n";

这会产生以下输出:

$ perl example.pl
x1:70 y1:50
x:50 y:70

如果参数以逐个引用的方式处理,x不应该等于x1而y等于y1吗?

3 个答案:

答案 0 :(得分:8)

Perl总是通过引用来调用。您声明($x1, $y1) = @_ 复制原始参数值,因为@_将别名保存到原始参数。

来自perlsub联机帮助页:

  

传入的任何参数都显示在数组@_中。因此,如果您使用两个参数调用函数,那么这些参数将存储在$ [0]和$ [1]中。数组@_是一个本地数组,但它的元素是实际标量参数的别名。特别是,如果更新元素$ _ [0],则更新相应的参数(如果不可更新,则会发生错误)。

答案 1 :(得分:3)

要修改sub之外的值,您必须修改@_的值。

以下sub interchange 修改值:

sub interchange {
    ($x1, $y1) = @_; # this line copies the values to 2 new variables

    $z1 = $x1;
    $x1 = $y1;
    $y1 = $z1;

    $_[0] = $x1; # this line added to change value outside sub
    $_[1] = $y1; # this line added to change value outside sub

    print "x1:$x1 y1:$y1\n";
}

这给出了输出:

x1:70 y1:50
x:70 y:50

此处有更多信息:http://www.cs.cf.ac.uk/Dave/PERL/node51.html

但是,引用这篇文章:

  

您可以看到该函数能够影响主程序中的@array变量。通常,这被认为是错误的编程实践,因为它不会将函数与程序的其余部分隔离开来。

答案 2 :(得分:-2)

我刚开始使用Perl,我相信你误解了你传递给子程序的内容。当你传递$ x和$ y时,你传递的是标量$ x和$ y被设置为。你需要显式传递一个引用,它也恰好是一个标量(是唯一允许传递给子程序的东西)。我知道你来自哪里,因为对于数组和哈希,因为你需要将引用传递给那些引用,所以你认为事物是引用引用的。

此代码应该执行您正在寻找的内容:

#!/usr/bin/perl

$x=50;
$y=70;

sub interchange {
    ($x1, $y1) = @_;

    $z1 = $$x1; # Dereferencing $x1
    $$x1 = $$y1; # Dereferencing $x1 and $y1
    $$y1 = $z1; # Dereferencing $y1

    print "x1:$$x1 y1:$$y1\n";
}

&interchange (\$x, \$y); # Passing references to $x and $y, not their values

print "x:$x y:$y\n";

我使用\ $ x和\ $ y传递对$ x和$ y的引用。然后,我使用$$ x和$$ y在子例程中取消引用它们。