我在使用Erlang模块时遇到了一些麻烦。这是我写的那个:
- 模(basic_gen_server)。 -export([start / 1,call / 2,cast / 2])。
start(Module) ->
register(server, spawn(basic_gen_server,gen_server_loop,[Module, Module:init()])), server.
call(Pid,Request) ->
Pid ! {call, self(), Request},
receive
Reply -> Reply
end.
cast(Pid,Request) ->
Pid ! {cast, self(), Request},
receive
_ -> ok
end.
gen_server_loop(Module, CurrentState) ->
io:fwrite("gen_server_loop~n", []),
receive
{call, CallPid, Request} ->
{reply, Reply, NewState} = Module:handle_call(Request,self(),CurrentState),
CallPid ! Reply,
gen_server_loop(Module, NewState);
{cast, CastPid, Request} ->
{noReply, NewState} = Module:handle_cast(Request, CurrentState),
CastPid ! noReply,
gen_server_loop(Module, NewState)
end.
以下是定义的回调模块:
% Written by Caleb Helbling
% Last updated Oct 10, 2014
-module(name_server).
-export([init/0, add/3, whereis/2, handle_cast/2,
handle_call/3, handle_swap_code/1]).
%% client routines
add(ServerPid, Person, Place) ->
basic_gen_server:cast(ServerPid, {add, Person, Place}).
whereis(ServerPid, Person) ->
basic_gen_server:call(ServerPid, {whereis, Person}).
%% callback routines
init() ->
maps:new().
handle_cast({add, Person, Place}, State) ->
NewState = maps:put(Person, Place, State),
{noreply, NewState}.
handle_call({whereis, Person}, _From, State) ->
Reply = case maps:find(Person, State) of
{ok, Place} -> Place;
error -> error
end,
NewState = State,
{reply, Reply, NewState}.
handle_swap_code(State) ->
{ok, State}.
尝试使用以下命令初始化服务器时:
MyServer = basic_gen_server:start(name_server).
我得到以下调试输出:
=ERROR REPORT==== 29-Oct-2014::12:41:42 ===
Error in process <0.70.0> with exit value: {undef,[{basic_gen_server,gen_server_loop,[name_server,#{}],[]}]}
从概念上讲,我理解将串行代码放入基本服务器系统的概念,但我相信我有一个语法错误,我无法使用语法突出显示或谷歌找到。在此先感谢您的帮助!
答案 0 :(得分:1)
不导出函数gen_server_loop
。因此,您无法致电basic_gen_server:gen_server_loop(Module, Module:init())
,这就是spawn(basic_gen_server,gen_server_loop,[Module, Module:init()])
内发生的事情。
如果您阅读了错误消息,它会告诉您要在undefined(trougn undef
atom)中调用的函数。功能为{basic_gen_server,gen_server_loop,[name_server,#{}],[]}
,或您有{Module, Function, ListOfArgs, ...}
的位置。你总是应该检查
如果未定义函数,则不会编译所有本地调用(如loop(SomeArgs)
,未指定模块)。您可以动态进行本地调用(FuntionName(SomeArgs)
,无需模块名称)。
编辑。
你实际上可以使用lambda。有spawn/1
个函数,如果你愿意,它需要lambda(或fun
),所以你可以调用spawn( fun local_functino/0).
。唯一的问题是你的fun
不能接受任何参数,但是有一种解决方法,使用闭包。
spawn(fun () ->
gen_server_loop(Module, Module:init())
end).
gen_serve_loop
保留本地电话。