2011-09-29 25 views
8

Tôi đã nghe nói rằng việc chỉ định các bản ghi thông qua bộ dữ liệu trong mã là một thực hành không tốt: Tôi phải luôn sử dụng các trường bản ghi (#record_name{record_field = something}) thay vì các bộ dữ liệu đơn thuần {record_name, value1, value2, something}.Làm thế nào để đối sánh với ets: khớp với một bản ghi trong Erlang?

Nhưng làm cách nào để khớp với bản ghi đối với bảng ETS? Nếu tôi có một bảng có hồ sơ, tôi chỉ có thể khớp với những điều sau đây:

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

Rõ ràng là khi tôi thêm một số trường mới vào định nghĩa bản ghi, mẫu này sẽ ngừng hoạt động.

Thay vào đó, tôi muốn sử dụng một cái gì đó như thế này:

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

Thật không may, nó sẽ trả về một danh sách trống.

Trả lời

16

Nguyên nhân gây ra sự cố của bạn là những trường không xác định được đặt thành khi bạn thực hiện #record_name{record_field=something}. Đây là cú pháp để tạo một bản ghi, tại đây bạn đang tạo một bản ghi/bộ dữ liệu mà ETS sẽ hiểu là mẫu. Khi bạn tạo một bản ghi thì tất cả các trường không xác định sẽ nhận được các giá trị mặc định của chúng, hoặc các giá trị được xác định trong định nghĩa bản ghi hoặc giá trị mặc định mặc định undefined.

Vì vậy, nếu bạn muốn cung cấp cho các trường giá trị cụ thể thì bạn phải rõ ràng làm điều này trong hồ sơ, ví dụ #record_name{f1='$1',f2='$2',record_field=something}. Thông thường khi sử dụng hồ sơ và cược bạn muốn đặt tất cả các trường không xác định thành '_', biến "không quan tâm" cho phù hợp với cược. Có một cú pháp đặc biệt cho việc này bằng cách sử dụng tên trường đặc biệt và bất hợp pháp, tên là _. Ví dụ: #record_name{record_field=something,_='_'}.

Lưu ý rằng trong ví dụ của bạn, bạn đã đặt thành phần tên bản ghi trong bộ thành '$ 1'. Bộ tuple đại diện cho một bản ghi luôn có tên bản ghi là phần tử đầu tiên. Điều này có nghĩa là khi bạn tạo bảng ets, bạn nên đặt vị trí quan trọng bằng {keypos,Pos} thành một cái gì đó khác với mặc định 1 nếu không sẽ không có bất kỳ chỉ mục nào và tệ hơn nếu bạn có một bảng kiểu 'set' hoặc 'ordered_set' chỉ nhận được 1 phần tử trong bảng. Để lấy chỉ mục của trường bản ghi, bạn có thể sử dụng cú pháp #Record.Field, trong ví dụ #record_name.record_field.

9

Hãy thử sử dụng

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

Xem this cho lời giải thích.