是否可以使用对象作为哈希键?
例如,下面的代码允许我使用MyClass的示例作为键,但是当我遍历这些键并试图调用get_value
方法时,我得到了错误:
无法通过包“MyClass=HASH(0x12a4040)”定位对象方法“get_value”(可能您忘记加载“MyClass=HASH(0x12a4040)"?)
package MyClass;
use strict;
sub new
{
my $class = shift;
my $self = {
_value => shift
};
bless $self, $class;
return $self;
}
sub get_value {
my($self) = @_;
return $self->{_value};
}
my %hash = ();
%hash->{new MyClass(1)} = 0;
%hash->{new MyClass(2)} = 1;
for my $key (keys %hash)
{
print $key->get_value;
}
3条答案
按热度按时间u7up0aaq1#
默认情况下,Perl中的所有哈希键都是字符串,所以在代码中发生的事情(也有其他问题)是将对象转换为字符串并存储字符串。
一般来说,如果你想使用一个对象作为键,最简单的方法是使用两个数据结构,一个保存你的对象(数组),另一个将对象Map到一些值(哈希)。也可以创建一个绑定哈希,它将支持对象作为键,但通常,绑定哈希会比简单地使用两个数据结构慢。
标准模块Tie::RefHash提供了一种使用对象(和其他引用)作为散列键(当您取回它们时,它们可以正常工作)的机制。
dy1byipe2#
任何用作散列键的东西都是字符串化的。所以当你把对象用作散列键时,你只会得到它的字符串表示,而不是实际的对象本身。
真实的问题是,你到底为什么要这么做?
此外,将值赋给哈希的语法是
$hash{key} = $val
;箭头用于处理哈希引用。如果你想将对象与其他值相关联,一种方法是使用哈希数组,例如。
然后你可以调用
$foo[0]{obj}->get_value()
;如果你只是想让你的对象能够返回一些唯一的每个示例的ID,你可以添加一个方法,利用Scalar::Util的
refaddr
运算符:更多信息:perlobj,perldata,perlreftut,Scalar::Util
iecba09b3#
对于那些使用
convert_blessed
对JSON序列化的对象进行散列:我们使用JSON的TO_JSON钩子序列化字符串化的对象,并返回一个哈希对象:
然后,使用
JSON::to_json
进行字符串化:Perl对
a
和d
键的重新排序不一致,这使得字符串化对象上的散列不可靠。修复方法是使用
canonical
选项,如下所示:注:大对象将有巨大的JSON键,所以要小心。