Как сопоставить ets: сопоставить с рекордом в Erlang? - PullRequest
8 голосов
/ 29 сентября 2011

Я слышал, что указание записей через кортежи в коде - плохая практика: я всегда должен использовать поля записей (#record_name{record_field = something}) вместо простых кортежей {record_name, value1, value2, something}.

Но как мне сопоставитьзапись против таблицы ETS?Если у меня есть таблица с записями, я могу сопоставить только следующее:

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

Очевидно, что после добавления новых полей в определение записи это сопоставление с образцом перестанет работать.

Вместо этого я хотел бы использовать что-то вроде этого:

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

К сожалению, он возвращает пустой список.

Ответы [ 3 ]

16 голосов
/ 29 сентября 2011

Причиной вашей проблемы является то, какие неопределенные поля установлены, когда вы делаете #record_name{record_field=something}.Это синтаксис для создания записи, здесь вы создаете запись / кортеж, который ETS будет интерпретировать как шаблон.Когда вы создаете запись, тогда все неопределенные поля получат свои значения по умолчанию, либо те, которые определены в определении записи, либо значение по умолчанию undefined.

Так что, если вы хотите дать полям определенные значения, то вы должныявно сделайте это в записи, например #record_name{f1='$1',f2='$2',record_field=something}.Часто при использовании записей и ets вы хотите установить все неуказанные поля равными '_', «переменная пофиг» для соответствия ets.Для этого существует специальный синтаксис, использующий специальное и в противном случае недопустимое имя поля _.Например, #record_name{record_field=something,_='_'}.

Обратите внимание, что в вашем примере вы установили элемент имени записи в кортеже равным '$ 1'.Кортеж, представляющий запись, всегда имеет имя записи в качестве первого элемента.Это означает, что когда вы создаете таблицу ets, вы должны установить для ключевой позиции с помощью {keypos,Pos} значение, отличное от значения по умолчанию 1, иначе индексирование не будет и хуже, если у вас есть таблица типа 'set' или 'order_set 'вы получите только 1 элемент в таблице.Чтобы получить индекс поля записи, вы можете использовать синтаксис #Record.Field, в вашем примере #record_name.record_field.

9 голосов
/ 29 сентября 2011

Попробуйте использовать

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

См. это для объяснения.

4 голосов
/ 29 сентября 2011

Формат, который вы ищете: #record_name {record_field = что-то, _ = '_'}

http://www.erlang.org/doc/man/ets.html#match-2

http://www.erlang.org/doc/programming_examples/records.html (см. 1.3 Создание записи)

...