我从Learn you some erlang for great good复制gen_server实现代码,并创建一个名为kitty_gen_server.erl
的文件。然后我在erlang shell中运行以下命令:
$ erl
Erlang/OTP 19 [erts-8.0.2] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]
Eshell V8.0.2 (abort with ^G)
1> c(kitty_gen_server).
{ok,kitty_gen_server}
2> P = kitty_gen_server:start_link().
{ok,<0.64.0>}
3> kitty_gen_server:close_shop(P).
** exception exit: {{function_clause,
[{gen,do_for_proc,
[{ok,<0.64.0>},#Fun<gen.0.62797829>],
[{file,"gen.erl"},{line,253}]},
{gen_server,call,2,[{file,"gen_server.erl"},{line,200}]},
{erl_eval,do_apply,6,[{file,"erl_eval.erl"},{line,674}]},
{shell,exprs,7,[{file,"shell.erl"},{line,686}]},
{shell,eval_exprs,7,[{file,"shell.erl"},{line,641}]},
{shell,eval_loop,3,[{file,"shell.erl"},{line,626}]}]},
{gen_server,call,[{ok,<0.64.0>},terminate]}}
in function gen_server:call/2 (gen_server.erl, line 204)
4>
我确信代码是从learn you some erlang for greate good
下载的,但我不知道为什么不能执行。
我的系统是OS X 10.11,Erlang 19。
以下是代码:
-module(kitty_gen_server).
-behaviour(gen_server).
-export([start_link/0, order_cat/4, return_cat/2, close_shop/1]).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
terminate/2, code_change/3]).
-record(cat, {name, color=green, description}).
%%% Client API
start_link() ->
gen_server:start_link(?MODULE, [], [{debug,[trace]}]).
%% Synchronous call
order_cat(Pid, Name, Color, Description) ->
gen_server:call(Pid, {order, Name, Color, Description}).
%% This call is asynchronous
return_cat(Pid, Cat = #cat{}) ->
gen_server:cast(Pid, {return, Cat}).
%% Synchronous call
close_shop(Pid) ->
gen_server:call(Pid, terminate).
%%% Server functions
init([]) -> {ok, []}. %% no treatment of info here!
handle_call({order, Name, Color, Description}, _From, Cats) ->
if Cats =:= [] ->
{reply, make_cat(Name, Color, Description), Cats};
Cats =/= [] ->
{reply, hd(Cats), tl(Cats)}
end;
handle_call(terminate, _From, Cats) ->
{stop, normal, ok, Cats}.
handle_cast({return, Cat = #cat{}}, Cats) ->
{noreply, [Cat|Cats]}.
handle_info(Msg, Cats) ->
io:format("Unexpected message: ~p~n",[Msg]),
{noreply, Cats}.
terminate(normal, Cats) ->
[io:format("~p was set free.~n",[C#cat.name]) || C <- Cats],
ok.
code_change(_OldVsn, State, _Extra) ->
%% No change planned. The function is there for the behaviour,
%% but will not be used. Only a version on the next
{ok, State}.
%%% Private functions
make_cat(Name, Col, Desc) ->
#cat{name=Name, color=Col, description=Desc}.
答案 0 :(得分:4)
kitty_gen_server:start_link/0
会在成功时返回一个元组{ok, Pid}
,您可以直接在[{1}}中存储,因此您的下一个电话会将P
传递给{ok, Pid}
只是Pid。您需要使用模式匹配仅将Pid存储在kitty_gen_server:close_shop/1
:
P