以下是我设置的一些测试,以帮助我理解哈希和参考:
my %record1 = ( "Name" => "My Name");
my %record2 = %record1;
my $record3 = \%record1;
$record1{'test'}= "yes";
print \%record1 ;
print "\n";
print %record1;
print "\n";
print \%record2;
print "\n";
print %record2;
print "\n";
print %$record3;
和
sub some_func{
%some_hash = ();
...
return %some_hash;
}
%some_hash2 = some_func(); # created new hash?
sub some_func2{
%some_hash = ();
...
return \%some_hash
}
$some_hash_ref3 = some_func2(); # ref to original hash?
答案 0 :(得分:1)
首先:
#!/usr/bin/env perl
use strict;
use warnings;
use Scalar::Util qw( refaddr );
my %record1 = ("Name" => "My Name");
printf "Address of %%record1 = %d\n", refaddr \%record1;
my %record2 = %record1;
printf "Address of %%record2 = %d\n", refaddr \%record2;
my $record3 = \%record1;
printf "Address of hash pointed to by \$record3 = %d\n", refaddr $record3;
输出:
Address of %record1 = 140595226123056 Address of %record2 = 140595226215352 Address of hash pointed to by $record3 = 140595226123056
这表明%record1
和%record2
是不同的哈希值,而$record3
指向%record1
。
接下来,
sub some_func{
%record1 = ();
return %record1
}
%record2 = some_func(); # created new hash?
哎哟!您正在清除%record1
哈希(即从中删除所有键和值)。 %record1
存在于此函数之外。这个函数唯一返回的是一个空列表。
然后%record2 = some_func()
会做两件事:在函数体中,它会清除%record1
。并且,因为它返回空列表,它还会清除%record2
中的所有键和值。
现在,添加
printf "Address of %%record1 = %d\n", refaddr \%record1;
printf "Address of %%record2 = %d\n", refaddr \%record2;
在%record2 = some_func()
之后,您会发现%record1
和%record2
仍然是相同的哈希值。但是,它们都是空的:
use Data::Dumper;
print Dumper $_ for \(%record1, %record2);
输出:
$VAR1 = {}; $VAR1 = {};
最后,请注意:
$record3 = some_func(); # ref to original hash?
我们已经确定some_func
返回空列表。但是,因为您要将返回值分配给标量,所以您在返回的列表上强制使用标量上下文。 $record3
将获取返回列表中的最后一个元素,而不是返回列表中的元素数。在这种情况下,这将是undef
,因为返回的列表中没有元素。在数字上下文中,undef将被解释为0
。 (感谢David Cross抓住我的阵列/列表混乱)。
$record3
不再是对任何内容的引用。
答案 1 :(得分:1)
record2是一个“浅薄的”' record1的副本?
是的,%record1
和%record2
是不同的哈希值,%record2
包含%record1
内容的(浅)副本。
record3是record1的哈希引用(指针)?
是的,$record3
包含对哈希%record1
的引用。
$ perl -e'
my %record1 = ( "Name" => "My Name");
my %record2 = %record1;
my $record3 = \%record1;
CORE::say( \%record1 == \%record2 ? "same" : "different" );
CORE::say( \%record1 == $record3 ? "same" : "different" );
'
different
same
请注意,虽然引用和指针非常相似,但它们并不相同。引用是一个指针,您无法在其上执行算术运算。 Perl只有引用。
创建了新哈希?
没有。 my
创建新变量,但您没有使用my
。首次遇到对它们的引用(因此在编译时而不是在调用%some_hash
期间)时会创建未声明的变量,例如some_func
。
此外,some_func
没有返回哈希值。除了潜艇的标量之外,不可能返回任何东西。 (另外,除了标量之外,不可能将任何内容传递给子。)some_func
实际上会返回%record1
的内容,这是一个空列表情况下。
引用原始哈希?
是。返回的标量(对%some_hash
的引用)被复制到$some_hash_ref3
,因此$some_hash_ref3
包含对%some_hash
的引用。