2011-09-29 8 views
8

Ho sentito dire che specificare i record tramite tuple nel codice è una cattiva pratica: dovrei sempre usare i campi dei record (#record_name{record_field = something}) invece delle semplici tuple {record_name, value1, value2, something}.Come abbinare le partite: confronto con un record in Erlang?

Ma come faccio a far corrispondere il record con una tabella ETS? Se ho una tabella con i record, posso abbinare solo con il seguente:

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

E 'ovvio che una volta aggiungo alcuni nuovi campi per la definizione record di questo pattern match smetterà di funzionare.

Invece, vorrei usare qualcosa di simile:

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

Purtroppo, restituisce una lista vuota.

risposta

16

La causa del problema è l'impostazione dei campi non specificati quando si esegue un #record_name{record_field=something}. Questa è la sintassi per che crea un record, qui si sta creando un record/tupla che ETS interpreterà come un modello. Quando crei un record, tutti i campi non specificati avranno i loro valori predefiniti, uno definito nella definizione del record o il valore predefinito predefinito undefined.

Quindi, se si desidera fornire valori specifici per i campi, è necessario farlo esplicitamente nel record, ad esempio #record_name{f1='$1',f2='$2',record_field=something}. Spesso quando si utilizzano record e ets si desidera impostare tutti i campi non specificati su '_', la "non badare alla variabile" per l'abbinamento di ets. C'è una sintassi speciale per questo usando il nome di campo speciale, o altrimenti illegale, _. Ad esempio #record_name{record_field=something,_='_'}.

Si noti che nell'esempio è stato impostato l'elemento nome record nella tupla su "$ 1". La tupla che rappresenta un record ha sempre il nome del record come primo elemento. Ciò significa che quando crei la tabella ets dovresti impostare la posizione della chiave con {keypos,Pos} su un valore diverso da quello predefinito 1 altrimenti non ci sarà alcuna indicizzazione e peggio se hai una tabella di tipo 'set' o 'ordered_set' lo farai ottieni solo 1 elemento nella tabella. Per ottenere l'indice di un campo di record, è possibile utilizzare la sintassi #Record.Field nell'esempio #record_name.record_field.

9

Provare a utilizzare

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

Vedi this per la spiegazione.