2011-09-29 22 views
8

コード内のタプルを使ってレコードを指定するのは悪い習慣であると聞いています。普通のタプル{record_name, value1, value2, something}の代わりに常にレコードフィールド(#record_name{record_field = something})を使用する必要があります。etsの一致方法:Erlangのレコードとの一致?

しかし、どのようにレコードをETSテーブルと照合するのですか?私はレコードを持つテーブルを持っている場合は、私は次のように一致させることができます:私がレコード定義にいくつかの新しいフィールドを追加したら、このパターンマッチは動作を停止しますことは明らかである

ets:match(Table, {$1,$2,$3,something} 

代わりに、私はこのようなものを使用したいと思います:

ets:match(Table, #record_name{record_field=something}) 

残念ながら、それは空のリストを返します。

答えて

16

#record_name{record_field=something}を実行すると、指定されていないフィールドが設定されているという問題が発生します。これはの構文で、レコードを作成します。ここでは、ETSがパターンとして解釈するレコード/タプルを作成しています。レコードを作成すると、指定されていないすべてのフィールドは、レコード定義で定義されたデフォルト値、またはデフォルトのデフォルト値undefinedのいずれかのデフォルト値を取得します。

フィールドに特定の値を指定する場合は、レコード内で明示的に行う必要があります(例:#record_name{f1='$1',f2='$2',record_field=something})。多くの場合、レコードとetsを使用するときは、指定されていないすべてのフィールドを'_'に設定する必要があります。etsに一致する "do not care変数"。特殊な、それ以外の違法なフィールド名_を使用して、このための特別な構文があります。たとえば、#record_name{record_field=something,_='_'}です。

あなたの例では、タプルのというレコード名の要素が '$ 1'に設定されていることに注意してください。レコードを表すタプルは、常に最初の要素としてレコード名を持ちます。つまり、etsテーブルを作成するときに、{keypos,Pos}のキー位置をデフォルトの1以外の値に設定する必要があります。そうしないと、インデックスが作成されず、 'set'または 'ordered_set'タイプのテーブルがあると悪化します。テーブルの要素を1つだけ取得します。レコードフィールドのインデックスを取得するには、#record_name.record_fieldという例では、#Record.Fieldの構文を使用できます。あなたが探している

9

ets:match(Table, #record_name{record_field=something, _='_'}) 

を使用してみてください説明についてthisを参照してください。