似乎Perl只能将字符串作为哈希的键。 (在某个版本的Perl中是否已经更改了?)仅限于能够使用字符串作为键是非常有限的。如果我想要一个对象或一个数组作为关键怎么办?在Python中,很容易使用数组,元组和其他可以比较的对象,如dict键。 Perl确实能够比较数组之类的东西是否相等,所以我不明白为什么它们不能用作映射类型键。
在Perl中没有办法使用任何密钥类型吗?是否有提供此功能的模块?
答案 0 :(得分:3)
AFAIK Perl简单地将键字串化?
package Foo;
use Moose;
use overload ('""' => \&stringify);
sub stringify {
return "xxx";
}
package main;
use v5.10;
use Data::Dump 'pp';
my $foo = Foo->new;
my $hash = {$foo => 'bar'};
say pp($hash); // { xxx => "bar" }
这样您也可以使用任何您想要的哈希键。另请参阅此thread on Perl Monks。
至于平等,请看equality operators in perlop。 ==
运算符以数字方式进行比较,eq
运算符按字符串进行比较。这意味着,例如(4, 2) == (1, 2)
为真(scalar (4, 2)
为2
),这可能会让您大吃一惊。
答案 1 :(得分:3)
与你所说的相反,Perl没有能力像你声称的那样比较像数组这样的东西。首先,Perl没有数组相等的定义。如果定义需要比较数组的内容,那么Perl对于大多数可以在数组中找到的东西都没有相等的定义。
最接近的Perl对于相等数组的定义是它们的地址。如果这就是你想要使用的东西,那么它很容易:
$key = ['a', 'b'];
$hash{$key} = [ $key, $val ]; # Prevents the key from being freed.
print $hash{$key}[1];
否则,Perl会让你实现你想要的东西,而不是强迫你使用它提供的东西。我看到两种主要方法。
捆绑哈希,基本上是代码,它提供哈希的接口而不实际是哈希表,可以支持任何密钥类型。您可以使用它来定义数组相等的版本。甚至可能有一个现有的模块(虽然我很快就没有看到一个模块)。
另一种方法是创建一个从键表达式生成唯一键的函数。
sub key{ "@_" } # Overly simplistic?
$hash{key('a', 'b')} = $val;
print $hash{key('a', 'b')};
答案 2 :(得分:3)
是的,CPAN上有这个模块:Tie::Hash::StructKeyed。它考虑了整个结构,但作为快照。每个/键将返回原始参考。
答案 3 :(得分:1)
是的,在5.10之前使用fieldhashes(Hash::Util::FieldHash和5.10之前的Hash::Util::FieldHash::Compat)将哈希注册为fieldhashes,并且可以使用任何引用(因此,任何对象)作为这些哈希的密钥(它实际上是对引用进行编号,并提供了跨线程处理CLONEing和收集密钥的垃圾的逻辑),例如:
use Hash::Util qw/fieldhashes/;
fieldhashes \my (%foo, %bar, %baz);
my %data = (a => 1, b => 2, c => 3);
my $stuff = {t => 2, u => 3, l => 9};
$foo{\%data} = 'x';
$foo{$stuff} = 'a';
$bar{\%data} = 'y';
$bar{$stuff} = 'b';
$baz{\%data} = 'z';
$baz{$stuff} = 'c';
print "$foo{\%data} $bar{\%data} $baz{\%data}\n";
print "$foo{$stuff} $bar{$stuff} $baz{$stuff}\n";