gpt4 book ai didi

perl - Perl 子例程是按引用调用还是按值调用?

转载 作者:行者123 更新时间:2023-12-03 00:57:59 25 4
gpt4 key购买 nike

我正在尝试弄清楚 Perl 子例程以及它们是如何工作的。来自 perlsub我知道子例程是按引用调用的,并且需要赋值(如 my(@copy) = @_; )才能将它们转换为按值调用。

在下面,我看到change被称为引用调用,因为“a”和“b”被更改为“x”和“y”。但我很困惑为什么数组没有用额外的元素“z”扩展?

use strict;
use Data::Dumper;

my @a = ( "a" ,"b" );

change(@a);

print Dumper(\@a);

sub change
{
@_[0] = "x";
@_[1] = "y";
@_[2] = "z";
}

输出:

$VAR1 = [
'x',
'y'
];

在下面,我传递一个散列而不是一个数组。为什么 key 没有从“a”更改为“x”?

use strict;
use Data::Dumper;

my %a = ( "a" => "b" );

change(%a);

print Dumper(\%a);

sub change
{
@_[0] = "x";
@_[1] = "y";
}

输出:

$VAR1 = {
'a' => 'y'
};

我知道真正的解决方案是使用\@通过引用传递数组或散列,但我想准确了解这些程序的行为。

最佳答案

Perl 总是通过引用传递。只是有时调用者会传递临时标量。

您必须意识到的第一件事是 subs 的参数只能是一件事:标量列表。* 不能将数组或哈希传递给它们。评估数组和散列,返回其内容的列表。这意味着

f(@a)

与**相同

f($a[0], $a[1], $a[2])

Perl 通过引用传递。具体来说,Perl 将每个参数别名为 @_ 的元素。修改元素 @_ 将更改 $a[0] 返回的标量等,从而修改 @a 的元素。

第二个重要的事情是数组或散列元素的键决定了元素在结构中的存储位置。否则,$a[4]$h{k} 将需要查看数组或散列的每个元素以找到所需的值。这意味着 key 不可修改。移动值需要使用新键创建新元素并删除旧键处的元素。

因此,每当您获取数组或哈希的键时,您都会获得键的副本。可以这么说,新鲜的标量。

回到问题

f(%h)

与**相同

f(
my $k1 = "a", $h{a},
my $k2 = "b", $h{b},
my $k2 = "c", $h{c},
)

@_ 仍然是 %h 返回的值的别名,但其中一些只是用于保存键的临时标量。改变这些不会有持久的影响。

* — 一些内置函数(例如 grep)更像是流程控制语句(例如 while)。它们有自己的解析规则,因此不限于传统的子模型。

** - 原型(prototype)可以影响参数列表的计算方式,但它仍然会产生标量列表。

关于perl - Perl 子例程是按引用调用还是按值调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5741042/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com