Erlang基本通用服务器调试器输出解释

Erlang基本通用服务器调试器输出解释,erlang,gen-server,Erlang,Gen Server,我在使用Erlang模块时遇到了一些问题。这是我写的一篇: -模块(基本发电机服务器)。 -导出([start/1、call/2、cast/2]) 下面是定义的回调模块: % 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

我在使用Erlang模块时遇到了一些问题。这是我写的一篇:

-模块(基本发电机服务器)。 -导出([start/1、call/2、cast/2])

下面是定义的回调模块:

% 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,#{}],[]}]}
=错误报告===2014年10月29日::12:41:42===
使用退出值进行处理时出错:{unde,[{basic_gen_server,gen_server_loop,[name_server,{}],]}

从概念上讲,我理解将串行代码转换成基本服务器系统的概念,但我相信我有一个语法错误,我无法使用语法突出显示或Google找到它。提前感谢您的帮助

功能
gen\u server\u循环
未导出。因此,您不能调用
basic\u gen\u server:gen\u server\u循环(Module,Module:init())
,这就是
spawn(basic\u gen\u server,gen\u server\u循环,[Module,Module:init()])内部发生的情况。

如果您阅读了错误消息,它会告诉您您正在尝试调用未定义的函数(trougn
undef
atom)。函数是
{basic_gen_server,gen_server_loop,[name_server,{}],]}
,或者您有
{Module,Function,ListOfArgs,…}
。你应该经常检查一下

  • 没有类型模块或函数名
  • 函数arity匹配调用中的参数数(错误消息中的列表)
  • 函数被导出
如果未定义函数,则所有本地调用(如
循环(SomeArgs)
,没有指定模块)都不会编译。您还可以动态地进行本地调用(
FuntionName(SomeArgs)
,而不需要模块名)


在评论本地呼叫需求后编辑

实际上你可以用lambda来做这个。有
spawn/1
function,它接受lambda(或者
fun
,如果您愿意),因此您可以调用
spawn(fun local\u functino/0)。
。唯一的问题是,您的
fun
不能接受任何参数,但有一种方法可以绕过它,使用闭包

spawn(fun () ->
         gen_server_loop(Module, Module:init())
      end).

gen\u serve\u loop
保持本地呼叫

我理解导出它的用途,但我们的任务明确要求我们只导出程序中的某些函数,即start/1、call/3和cast/2。有没有一种方法可以避免导出循环函数,该函数应该隐藏在模块接口中?有一句话与您的问题无关,我认为您应该删除gen_server cast接口中的receive bloc。它使强制转换同步。换成ok就行了。
spawn(fun () ->
         gen_server_loop(Module, Module:init())
      end).