ash*_*ony 1 arrays perl reference list
我需要将变量,列表和哈希传递给子例程,并从中获取更改而不返回。
此代码无法完成工作。
sub foo{
my $one = {$_[0]};
my @list = @{$_[1]};
my %hash = %{$_[2]};
print("\n inside foo: ${one}\n");
print("\n inside foo: $one @list $hash{'key'}\n");
$one = 2;
@list = (4,5,6);
my %hash2;
$hash2{'key'} = 'valueModified';
%hash = %hash2;
print("\n inside foo after Mod: $one\n");
print("\n inside foo after Mod: $one @list $hash{'key'}\n");
}
my $one = 1;
my @list = (1,2,3);
my %hash;
$hash{'key'} = 'value';
my @allLocalArgs = (\$one,\@list,\%hash);
foo(\@allLocalArgs);
print("\nafter foo modification: $one @list $hash{'key'}\n");
Run Code Online (Sandbox Code Playgroud)
输出:
inside foo: HASH(0x234a240)
inside foo: HASH(0x234a240)
inside foo after Mod: 2
inside foo after Mod: 2 4 5 6 valueModified
after foo modification: 1 1 2 3 value
Run Code Online (Sandbox Code Playgroud)
谢谢。
原则上,实际上几乎所有语言,您都希望传递引用调用者,指针或引用中的数据结构的对象。在Perl中,这将作为参考-而您正在这样做。
但是,然后在子目录中创建本地副本;的$one,@list以及%hash 在子是词法变量
本地子的范围,屏蔽/阴影在呼叫范围内的人。对这些所做的更改不会超出sub的范围。
而是直接使用传递的引用来写入调用者的数据。
sub foo {
my ($rscalar, $rary, $rhash) = @_;
$$rscalar = 2;
@$rary = (4,5,6);
$rhash->{'key'} = 'valueModified';
}
foo(\$one, \@list, \%hash);
Run Code Online (Sandbox Code Playgroud)
现在$one,,@list和%hash中的调用代码已更改。有关使用参考的详细信息,请参见教程perlreftut和参考perlref。
请注意,foo(\@allLocalArgs);该参数使用参数传递数组的引用,因此子元素接收一个元素-该数组的引用。您可以这样做,但是对于问题而言,它不是必需的,因此我将其删除并直接传递了参数列表。
要注意的另一件事是,参数是别名的@_-因此,如果@_直接在子目录中使用,则将在调用方中更改数据。因此,如果要传递标量变量,foo($one)则$_[0] = 2在$one调用方的子项中进行更改。我认为原则上最好避免这种情况;如果要更改呼叫者的数据,则应使其尽可能明确;通过参考。
术语说明
甲列表在Perl是用于在一个程序中移动数据的难以捉摸的,短暂的结构; 想一想堆栈中的一堆标量(值),它们将被使用并消失。也许将参数传递给函数(foo($v1, $v2)),或形成字符串(join '', $v1, $v2),或创建匿名数组引用([$v1, $v2]),等等。
一个阵列,在另一方面,是一种多值可变。就像哈希(关联数组)一样,它是一个多值变量,与标量相反,它是一个单值变量。
关于这一点已经写了很多。这里有一些链接很容易出现:有效的Perler文章(带有更多文章的链接),以及Stackoverflow页面Perl array vs list。
简而言之,您正在询问“标量,数组,哈希”。