2011-08-16 58 views
5

Perl似乎只能將字符串作爲哈希鍵。 (這在Perl的某個版本中是否發生了變化?)只能使用字符串作爲鍵是非常有限的。如果我想要一個對象或一個數組作爲關鍵字怎麼辦?在Python中,很容易使用數組,元組和其他可以比較的對象,如字典鍵。 Perl確實能夠比較數組之間的相等性,所以我不明白爲什麼它們不能用作映射類型的鍵。Perl有一個可以有任何類型鍵的關聯數組類型嗎?

在Perl中沒有使用任何鍵類型的方法嗎?有沒有提供這個模塊?

回答

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),這可能會讓你感到驚訝。

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')}; 
+0

Perl也可以比較數組的內容:print'ok'if(['a',1 ] ~~ ['a',1]); –

3

是的,在CPAN上有這個模塊:Tie::Hash::StructKeyed。它考慮到整個結構,但作爲快照。每個/鍵將返回原始參考。

1

是的,在5.10之前使用fieldhashes(對於5.10+和Hash::Util::FieldHash::Compat,對於5.10之前)使用fieldhashes,並且可以將任何引用(因此,任何對象)用作這些散列的關鍵字例如:

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"; 
相關問題