【发布时间】:2018-02-07 14:35:05
【问题描述】:
这是目录结构。
src/
动物.hrl
people.hrl
data_animal.erl
data_people.erl
test.erl
test_macro.erl
动物.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}]
突然间,我发现这两个函数共享相同的模式。然后我尝试编写一个宏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 个问题。
- 我的代码真的不像 Erlang 吗?它是从我公司的项目中提取的。我还在考虑面向对象编程吗?或者我公司的编程人员也是如此?
- 感谢@mlambichs 的建议。它有效,但我仍然想知道为什么我的代码会出现编译错误?是不是因为 Erlang 预处理器是一次性扫描器,所以无法识别
#Record{age=Age}? -
根据@mlambichs 的建议,我尝试更改宏
-define(get_list(DataMod, Record, Age), [P || P DataMod:get(Id) 结束, 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
【问题讨论】:
-
关于样式的注释(这可能会理所当然地解决您的问题)直接在 .erl 文件中定义记录。只有
animal.erl和people.erl并将接口函数写入数据,以便它们表现为自己的抽象数据类型。为了在 Erlangdom 中更进一步(并按照 Alan Kay 的意图使其成为 OOP),让people.erl和animal.erl模块定义进程,以便每个实例是动物或人。将接口函数写入那些进程作为访问器。通过这种方式,游戏服务器之类的东西在 Erlang 中得到了简化。 -
我想知道的是,为什么会出现编译错误?更重要的是,如果有人可以在不使用 list:foldl/3 的情况下优化我的代码,我将不胜感激。
-
宏定义的末尾好像缺少一个结束符")"
-
不,在 Fun 定义之前有一个开头的“(”,应该删除。如果添加额外的“)”,它将不起作用。
-
所以你需要有人来校对你工作或学校的语法,而不是真正指导你走向更一般意义上的更好的 Erlang。非常:-/
标签: compilation macros erlang record