5

Perl は、ハッシュのキーとして文字列しか持てないようです。(これは Perl の特定のバージョンで変更されましたか?) キーとして文字列しか使用できないのは非常に制限的です。オブジェクトまたは配列をキーにしたい場合はどうすればよいですか? Python では、配列、タプル、その他の比較可能なオブジェクトを dict キーとして簡単に使用できます。Perl には、配列のようなものを同等に比較する機能があります。そのため、それらをマッピング タイプのキーとして使用できない理由がわかりません。

Perl で任意のキー タイプを使用する方法はありませんか? これを提供するモジュールはありますか?

4

4 に答える 4

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" }

このようにして、ハッシュキーとして必要なものを使用することもできます。PerlMonksのこのスレッドも参照してください。

等式については、perlopの等式演算子を見てください。演算子は==数値で比較し、eq演算子は文字列で比較します。これは、たとえば(そのままで)(4, 2) == (1, 2)真であることを意味します。これはあなたにとって驚きかもしれません。scalar (4, 2)2

于 2011-08-16T07:12:18.343 に答える
3

あなたが言ったことに反して、Perl には、あなたが主張するように、配列のようなものを同等に比較する機能はありません。まず第一に、Perl には配列の等価性に関する定義がありません。また、定義で配列の内容を比較する必要がある場合、Perl には、配列で見つかるほとんどのものに対する等価性の定義もありません。

Perl が等値配列の定義に最も近いのは、それらのアドレスです。それがあなたが使いたいものなら、それはとても簡単です:

$key = ['a', 'b'];
$hash{$key} = [ $key, $val ];   # Prevents the key from being freed.
print $hash{$key}[1];

それ以外の場合、Perl は、提供されているものを強制的に使用するのではなく、必要なものを実装するかどうかをユーザーに任せます。主なアプローチは 2 つあります。

関連付けられたハッシュ (基本的に、実際にはハッシュ テーブルではなくハッシュのインターフェイスを提示するコード) は、任意のキー タイプをサポートできます。これを使用して、配列の等価性のバージョンを定義できます。既存のモジュールが存在する可能性もあります (非常に簡単な検索では見つかりませんでしたが)。

もう 1 つの方法は、キー式から一意のキーを生成する関数を作成することです。

sub key{ "@_" }  # Overly simplistic?
$hash{key('a', 'b')} = $val;
print $hash{key('a', 'b')};
于 2011-08-16T07:15:07.497 に答える
3

はい、CPAN にこのためのモジュールがあります: Tie::Hash::StructKeyed。構造全体が考慮されますが、スナップショットとして考慮されます。each/keys は元の参照を返します。

于 2011-08-16T09:51:57.450 に答える