作者frank1983 (What?)
看板Perl
标题Re: [问题] 删除或清空整个hash ?
时间Fri Sep 4 03:30:11 2009
※ 引述《abliou (把青春freeze)》之铭言:
: 这个文章让我想到几个问题..不过还是想不透...
: 就是由上面(1)中...输入到%h的匿名杂凑还会有value吗?(undef??)
: 然後再往後延伸一个问题...若我想要取出那个匿名杂凑的key-value要怎麽做?
: 我写了一小段..
: %h=({'ty'=>'g'},"ll");
: $h{'a'}=b ;
: print @{[keys(%h)]}[1] . $/ ;
: print ${@{[keys(%h)]}[1]}{'ty'} ;
: ===输出===
: HASH(0X288b0c)
: ==========
: 好像还是取不出hash那个的value...
关於第一个问题,
你是想问像 %h = ('key') 这样指定的话 $h{key} 的 value 是什麽吗?
use Data::Dumper;
my %h = ('key');
print Dumper($h{key});
答案是 undef
不过如果有宣告 use warnings; 的话 perl 会警告你 %h 只包含了奇数个元素
而匿名杂凑不可以直接当成杂凑的 key 使用,如
my %h = ( { 'ty' => 'g' } => 'll', a => 'b' ); # doesn't work!
就算可以,因为不同的匿名杂凑是不同的 reference,
所以 $h{{'ty' => 'g'}} 也不是 'll'!
由
http://perldoc.perl.org/perlfaq4.html
How can I use a reference as a hash key?
可知,hash 的 key 一定是 string
所以会如果在 key 中使用 reference 就会出现如你所看到的 HASH(0X288b0c)
基本上你是无法从 HASH(0X288b0c) 去反推原始的 object 的
不过 faq4 提供了两种解决办法:
第一种是使用 Hash::Util::FieldHash 这个 module (5.10 後是 core module)
范例如下:
use Hash::Util qw(fieldhash);
use Hash::Util::FieldHash qw(id_2obj);
use Data::Dumper;
fieldhash my %h;
my $foo = { 'ty' => 'g' };
%h = ( $foo => 'll', a => 'b' );
for my $key (keys(%h)) {
my $obj = id_2obj($key);
print Dumper(defined $obj ? $obj : $key)
}
其输出结果为 (%h 包含了两个 key):
$VAR1 = 'a';
$VAR1 = {
'ty' => 'g'
};
fieldhash 会定义一特殊的 hash,主要是用来实作 inside-out class
,请参考
http://perldoc.perl.org/Hash/Util/FieldHash.html
另一个方法是使用 Tie::RefHash 这个 module
它可将 reference 真正当成 hash key 来使用
范例如下:
use Data::Dumper;
use Tie::RefHash;
tie my %h, 'Tie::RefHash';
my $foo = { 'ty' => 'g' };
%h = ( $foo => 'll', a => 'b' );
for my $key (keys(%h)) {
print Dumper($key);
}
其输出结果为:
$VAR1 = {
'ty' => 'g'
};
$VAR1 = 'a';
上面两种方法都可以由 $h{$foo} 得到 'll'
最後,在将 reference 当成 hash key 时要特别小心
以免产生奇怪的 bug,或是造成 memory leak
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 61.59.233.171
1F:推 abliou:感谢! 09/04 09:22