我无法弄清楚如何将嵌套记录的结构转换为支持列表。我可以将个人记录转换为支持列表:
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 = [],
}).
我知道如何才能实现这一目标吗?
答案 0 :(得分: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))).
如果您想省去为每种相关类型扩展此问题的麻烦,我刚刚找到了这个runtime record_info,但我还没有尝试过。
答案 1 :(得分: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));