语法访问记录中的字段时出错

时间:2010-10-22 22:40:20

标签: erlang record

我遇到的问题应该很容易修复。在this之后,我正在尝试访问记录中的字段。这是一个展示我问题的简化示例:

-module(test).
-export([test/0]).

-record(rec, {f1=[], f2=[], f3=[]}).

test() ->
    Rec = #rec{f1=[1,2,3], f3=[4,5,6]},
    Fields = record_info(fields, rec),
    loop(Fields, Rec).

loop([Field|Fields], Rec) ->
    [Rec#rec.Field|loop(Fields, Rec)]; %% <-- This is line 12.
loop([], _Rec) ->
    [].

当我尝试编译测试时,出现语法错误:

./test.erl:12: syntax error before: Field

我做错了什么?

3 个答案:

答案 0 :(得分:2)

如果您只想枚举记录值,可以使用element/2并枚举从2(the first element is a record name)到tuple_size(记录)的元素。

如果要在运行时按名称访问记录字段,可以在编译时创建辅助proplist,如下所示:

Fields = lists:zip(record_info(fields, rec),
                   lists:seq(2, record_info(size, rec)))

请注意,record_info()始终在编译时进行评估。

然后使用与此类似的函数查询字段值:

get_record_value(Name, Record, Fields) ->
    case proplists:get_value(Name, Fields) of
        undefined ->
            undefined;
        N when is_integer(N) ->
            element(N, Record)
    end.

答案 1 :(得分:1)

记录在编译时转换为数组,这意味着所有字段访问都转换为erlang:element调用。因此,变量不能被使用,因为必须在编译时知道字段名称 - 正如Damg已经回答的那样。

我所知道的“变通方法”要么使用proplists,dicts等代替记录,要么使用Ulf Wiger的exprecs来生成记录访问功能。

答案 2 :(得分:0)

另一种方法是将记录转换为proplist并使用proplists库模块迭代或访问特定字段。这个例子:

-module(test).
-export([start/0]).
-record(test, {value1, value2, value3}).

start() ->
    R = #test{value1=1, value2=2, value3=3},
    Fields = record_info(fields, test),
    Values = tl(tuple_to_list(R)),
    lists:zip(Fields, Values).

将产生以下支持列表:

> c("test").
> Proplist = test:start().
[{value1,1},{value2,2},{value3,3}]

然后例如获取字段value2的值:

> proplists:get_value(value2, Proplist).
2