这是目录结构。
的src /
animal.hrl
people.hrl
data_animal.erl
data_people.erl
test.erl
test_macro.erl
animal.hrl
%% The record definition of animal.
-ifndef(ANIMAL).
-define(ANIMAL,true).
-record(animal,{
id,
animal_name,
age
}).
-endif.
people.hrl
%% The record definition of people.
-ifndef(PEOPLE).
-define(PEOPLE,true).
-record(people,{
id,
people_name,
age
}).
-endif.
data_animal.erl
%% The data file of animal.
-module(data_animal).
-include("animal.hrl").
%% API
-export([get/1,get_ids/0]).
get(1)->
#animal{
id=1,
animal_name="cat",
age=23
};
get(2)->
#animal{
id=2,
animal_name="dog",
age=19
};
get(3)->
#animal{
id=3,
animal_name="tiger",
age=23
};
get(4)->
#animal{
id=4,
animal_name="pig",
age=19
};
get(_)->
undefined.
get_ids()->
[1,2,3,4].
data_people.erl
%% The data file of people.
-module(data_people).
-include("people.hrl").
%% API
-export([get/1,get_ids/0]).
get(1)->
#people{
id=1,
people_name="John",
age=23
};
get(2)->
#people{
id=2,
people_name="Ken",
age=19
};
get(3)->
#people{
id=3,
people_name="Tom",
age=23
};
get(4)->
#people{
id=4,
people_name="Healthy",
age=19
};
get(_)->
undefined.
get_ids()->
[1,2,3,4].
请注意,对于data_animal.erl
和data_people.erl
,get/1
的参数是返回值的记录ID,而get_ids/0
的返回值是列表get/1
的参数。
test.erl
-module(test).
%% API
-export([get_animal_list/1,get_people_list/1]).
-include("animal.hrl").
-include("people.hrl").
get_animal_list(Age)->
Fun=fun(Id,Acc)->
case data_animal:get(Id) of
#animal{age=Age}=Conf->
[Conf|Acc];
_->
Acc
end
end,
lists:foldl(Fun,[],data_animal:get_ids()).
get_people_list(Age)->
Fun=fun(Id,Acc)->
case data_people:get(Id) of
#people{age=Age}=Conf->
[Conf|Acc];
_->
Acc
end
end,
lists:foldl(Fun,[],data_people:get_ids()).
我想获得动物和人的数据,年龄为23岁,所以我写了2个函数,get_animal_list/1, get_people_list/1
。
我跑
1> c(data_animal),c(data_people),c(test).
{ok,test}
2> test:get_people_list(23).
[{people,3,"Tom",23},{people,1,"John",23}]
3> test:get_animal_list(23).
[{animal,3,"tiger",23},{animal,1,"cat",23}]
突然间,我发现2个功能共享相同的模式。然后我尝试编写宏get_list
,然后进行2次调用。
test_macro.erl
-module(test_macro).
%% API
-export([get_animal_list/1,get_people_list/1]).
-include("animal.hrl").
-include("people.hrl").
-define(get_list(DataMod,Record,Age),(
Fun=fun(Id,Acc)->
case DataMod:get(Id) of
#Record{age=Age}=Conf->
[Conf|Acc];
_->
Acc
end
end,
lists:foldl(Fun,[],DataMod:get_ids())
)).
get_animal_list(Age)->
?get_list(data_animal,animal,Age).
get_people_list(Age)->
?get_list(data_people,people,Age).
但是我收到了编译错误:
4> c(test_macro).
test_macro.erl:22: syntax error before: ','
test_macro.erl:25: syntax error before: ','
test_macro.erl:4: function get_animal_list/1 undefined
test_macro.erl:4: function get_people_list/1 undefined
error
告诉我为什么〜y~y~
谢谢大家! 我现在有3个问题。
#Record{age=Age}
?根据@mlambrichs的建议,我尝试更改宏
-define(get_list(DataMod,Record,Age), [P || P< - lists:map(fun(Id) - > DataMod:get(Id)end, DataMod:get_ids()), P#Record.age =:=年龄] )。
进入一个函数
get_list(DataMod, Record, Age)->
[P || P <- lists:map(fun(Id) -> DataMod:get(Id) end,
DataMod:get_ids()),
P#Record.age =:= Age].
然后我收到编译错误:
syntax error before: Record
答案 0 :(得分:1)
错误的原因是错位的(&#39;应删除:
-define(get_list(DataMod,Record,Age), (
^^^
Fun=fun(Id,Acc)->
case DataMod:get(Id) of
#Record{age=Age}=Conf->
[Conf|Acc];
_->
Acc
end
end,
lists:foldl(Fun,[],DataMod:get_ids())
).
EDIT 您添加了一些我想开始回答的问题。
像这样:
get_list(DataMod, Age) ->
[ P || P = {_,_,_,A} <- lists:map(fun(Id) -> DataMod:get(Id) end,
DataMod:get_ids()),
A =:= Age].
修改
接受重写。你想要的是功能测试中两个列表的串联(你的测试/ 0,我的测试/ 1)。使用逗号不会为您执行此操作。 ; - )
test(X)->
?get_list(data_animal,X) ++
?get_list(data_people,X).
让我们修复get_list宏。你的宏定义get_list有3个参数,只需要2.当你在get_people_list / 1和get_animal_list / 1中使用Record时,为什么要使用Record作为参数?例如,试试这个:
-define(get_list(DataMod, Y),
case DataMod of
data_animal -> get_animal_list(Y);
data_people -> get_people_list(Y);
_Else -> []
end
)
总的来说,测试模块中有很多代码复制。作为@ yjcdll的建议的后续,将界面功能移动到动物和人们的自己的模块。
让我们看一下您的数据模块及其获取功能。
我建议将所有人的记录放在一个数组中,在你的情况下是在data_people模块中。
people() -> [
#people{ id=1, people_name="John", age=23 },
#people{ id=2, people_name="Ken", age=19 },
#people{ id=3, people_name="Tom", age=23 },
#people{ id=4, people_name="Healthy", age=19 } ].
接下来,您需要一个getter函数才能获得具有特定年龄的人:
get(Age) ->
[X || X <- people(), is_age( X, Age )].
is_age / 2函数将是:
is_age( Person, Age ) ->
Person#people.age =:= Age.
因此,在模块测试中,你的get_people_list / 1会变得更加简单。
get_people_list(Age) ->
data_people:get(Age).
等等。一直在寻找与您已经在某处使用过的代码看起来非常相似的代码。试着表现得像一个理智,懒惰的程序员。懒惰=好。 ; - )
编辑:OP必须坚持给出的模块。因此重写宏是:
-define(get_list(DataMod, Record, Age),
[P || P <- lists:map(fun(Id) -> DataMod:get(Id) end,
DataMod:get_ids()),
P#Record.age =:= Age]
).