1

我读过 perl 在执行子程序时使用引用调用。我编写了一段简单的代码来检查这个属性,但它的行为就像 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 吗?

4

3 回答 3

8

Perl 总是绝对是通过引用调用的。您的声明($x1, $y1) = @_正在复制原始参数值,因为 @_ 拥有原始参数的别名。

从 perlsub 手册页:

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

于 2014-06-05T15:15:33.210 回答
4

要修改 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 变量。通常,这被认为是不好的编程习惯,因为它没有将函数的作用与程序的其余部分隔离开来。

于 2014-06-05T15:08:35.260 回答
-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 在子例程中取消引用它们。

于 2014-06-05T15:19:49.297 回答