0

我无法弄清楚如何将嵌套记录的结构转换为 proplist 或从 proplist 转换。我可以通过以下方式将单个记录转换为 proplist:

lists:zip(record_info(fields,typea), tl(tuple_to_list(Atypea))).

但是当记录的结构包含其他记录的列表时,这显然会失败,如下所示:

-record(typec, {
  id = 0,
  name = <<"typec">>,
 })

-record(typeb, {
  id = 0,
  name = <<"typeb">>,
  typec_list = [],
 }).

-record(typea, {
  id = 0,
  name = <<"typea">>,
  typec_list = [],
  typeb_list = [],
 }).

知道如何实现这一目标吗?

4

2 回答 2

2

这可以工作:

to_proplist(C = #typec{}) -> lists:zip(record_info(fields, typec), tl(tuple_to_list(C)));
to_proplist(B = #typeb{}) ->
    B1 = B#typeb{typec_list = [to_proplist(C) || C <- B#typeb.typec_list]},
    lists:zip(record_info(fields, typeb), tl(tuple_to_list(B1)));
to_proplist(A = #typea{}) ->
    A1 = A#typea{typec_list = [to_proplist(C) || C <- A#typea.typec_list]},
    A2 = A1#typea{typeb_list = [to_proplist(B) || B <- A1#typea.typeb_list]},
    lists:zip(record_info(fields, typea), tl(tuple_to_list(A2))).

如果您想省去为每种涉及的类型扩展它的麻烦,我刚刚找到了这个运行时 record_info,但是我还没有尝试过。

于 2013-09-18T08:29:01.633 回答
2

filmor给出的解决方案的变化如下

to_proplist(Record) ->
    to_proplist(Record,[]).


to_proplist(Type = #typea{}, []) ->
    lists:zip(record_info(fields, typea), to_list(Type));

to_proplist(Type = #typeb{}, []) ->
    lists:zip(record_info(fields, typeb), to_list(Type));

to_proplist(Type = #typec{}, []) ->
    lists:zip(record_info(fields, typec), to_list(Type));

to_proplist([NotAType | Rest], Res) ->
    to_proplist(Rest, [to_proplist(NotAType,[])| Res]);

to_proplist([], Res) ->
    lists:reverse(Res);

to_proplist(Val, []) ->
    Val.


to_list(Type) ->
    [to_proplist(L,[]) || L <- tl(tuple_to_list(Type))].

这将适用于记录的所有组合。只有添加 case 子句才能支持其他记录。例子:

to_proplist(Type = #typed{}, []) ->
        lists:zip(record_info(fields, typed), to_list(Type));
于 2013-09-21T09:03:44.160 回答