没有引用的 Perl 参数修改

标签 perl

我只是在玩弄在不使用引用的情况下修改 Perl 子例程中的参数的概念。我在数组的情况下试过这个:

sub test {
  print "Trying to change ... \n";
  $_[0] = "Third";
  $_[1] = 100;
}

@a = ("First", 1, "Second", 2);

print "Before change : @a \n";
test(@a);
print "After change : @a \n";

输出:

Before change : First 1 Second 2
Trying to change ...
After change : Third 100 Second 2

换句话说,通过更改 @_ 的值来更改数组的元素。

但是在散列的情况下做同样的事情并没有给出预期的行为:

sub test {
  print "Trying to change ... \n";
  $_[0] = "Third";
  $_[1] = 100;
}

%h = ("First" => 1, "Second" => 2);

test(%h);

foreach ( keys %h ) {
  print "$_\n";
}

输出:

Trying to change ...
Second
First

为什么这件事在这两种情况下不同?

最佳答案

你被误导了

Perl 散列键不是普通的 Perl 标量值——为了提高速度,它们存储为简单的 C 字符串,但散列值 Perl 标量

在像 test(%h) 这样的调用中,Perl 从每个散列键字符串中创建一个临时的 Perl 标量并将它们与真实散列值标量一起传递

这意味着任何修改键字符串的尝试都只会更改临时标量,而不会反射(reflect)在散列中。但是您的代码确实改变了值

这是一个在子例程调用前后转储整个哈希的版本。您可以看到字符串 Third 已经丢失,但是 100 已分配给一个(随机)哈希值

use strict;
use warnings 'all';

use Data::Dump 'pp';

sub test {
  $_[0] = "Third";
  $_[1] = 100;
}

my %h = ("First" => 1, "Second" => 2);

printf "Before: %s\n", pp \%h;
test(%h);
printf "After:  %s\n", pp \%h;

输出

Before: { First => 1, Second => 2 }
After:  { First => 1, Second => 100 }

关于没有引用的 Perl 参数修改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37719086/

相关文章:

perl - 为什么相同数据的 MD5 哈希值在 Linux 和 Windows 上不同?

perl - OCSP resolve_blocking() 和 LWP::UserAgent

html - 如何使用正则表达式按其类删除整个 HTML 标记(及其内容)?

perl - OTRS PostmasterMailbox.pl 解析/MIME 类型

windows - ZMQ::LibZMQ3 和草莓 perl

Perl GetOptions 模块

perl - 什么时候使用 chomp?

perl - 当文件具有 tmp 扩展名时确定 Perl 中的视频扩展名

perl - 是否可以获得特定 Perl 类的所有有效方法?

HTML::TokeParser - 查找标签之间和之后的文本