我有一些类似字段的记录,如下:
-define(COMMON_FIELDS, common1, common2, common3).
-record(item1, a, b, c, ?COMMON_FIELDS).
-record(item2, x, y, z, ?COMMON_FIELDS).
但后来我需要为每条记录编写类似的代码:
Record#item1.common1,
Record#item1.common2,
Record#item1.common3
和
Record#item2.common1,
Record#item2.common2,
Record#item2.common3
是否可以编写一个函数来访问不同记录中的相同字段?
答案 0 :(得分:0)
是否可以编写一个函数来访问相同的字段 不同的记录?
1)多个函数子句中的模式匹配:
-module(x1).
-export([read/1]).
-define(COMMON_FIELDS, common1, common2, common3).
-record(item1, {x, ?COMMON_FIELDS}). %Note that you defined your records incorrectly.
-record(item2, {y, ?COMMON_FIELDS}).
read(#item1{common1=C1, common2=C2, common3=C3} = _Item) ->
io:format("~p, ~p, ~p~n", [C1, C2, C3]);
read(#item2{common1=C1, common2=C2, common3=C3} = _Item) ->
io:format("~p, ~p, ~p~n", [C1, C2, C3]).
...
25> c(x1).
{ok,x1}
26> rr(x1).
[item1,item2]
27> A = #item1{x=10, common1="hello", common2="world", common3="goodbye"}.
#item1{x = 10,common1 = "hello",common2 = "world",
common3 = "goodbye"}
28> B = #item2{y=20, common1="goodbye", common2="mars", common3="hello"}.
#item2{y = 20,common1 = "goodbye",common2 = "mars",
common3 = "hello"}
29> x1:read(A).
"hello", "world", "goodbye"
ok
30> x1:read(B).
"goodbye", "mars", "hello"
ok
注意导出语句 - 它是长度为1的列表,即模块导出一个函数。输出显示read()
函数可以读取任何一种类型的记录。
2)案例陈述:
如果出于某种原因,通过声明一个函数表示一个函数子句,您可以这样做:
read(Item) ->
case Item of
#item1{common1=C1, common2=C2, common3=C3} -> true;
#item2{common1=C1, common2=C2, common3=C3} -> true
end,
io:format("~p, ~p, ~p~n", [C1, C2, C3]).
答案 1 :(得分:0)
您可以使用parse_transe中的exprecs
解析变换。
-module(parse).
-compile({parse_transform, exprecs}).
-record(item1, {x, common1, common2}).
-record(item2, {y, common1, common2}).
-export_records([item1, item2]).
-export([p/0]).
f() ->
R1 = #item1{x=1, common1=foo1, common2=bar1},
R2 = #item2{y=2, common1=foo2, common2=bar2},
['#get-'(Field, Rec) || Field <- [common1, common2], Rec <- [R1, R2]].
...
1> c(parse).
{ok,parse}
2> parse:f().
[foo1,foo2,bar1,bar2]
答案 2 :(得分:0)
将公共字段分解为每个记录公司中的单个字段可能是有意义的,这些记录公司包含具有所有公共数据或甚至是数据的记录。然后重构代码,对其自己的函数进行所有常见处理。
您仍需要对每个顶级记录进行模式匹配以获取公共子记录。但是在某个地方你可能想要对每种记录类型进行特定的处理,你可以在那里匹配公共字段。
-record(common, {c1, c2, c3}).
-record(item1, {a, b, c, com}).
...
process_item(#item1{a=A, b=B, c=C, com=Com}) ->
process_abc(A, B, C),
process_common(Com),
...;
process_item(#item2{x=X, y=Y ...
这样的数据结构也可能表示使用新的Map数据类型而不是记录。