编写OTPgen_server大致上就是用你的代码填充一个预制模板,下面是一个例子。前一节分别列出了gen_server的各个区块。
例如之前填写gen_server模板获得的my_bank模块
-module(my_bank).
-author("YDQ").
%% API
-export([start/0, stop/0, new_account/1, deposit/2, withdraw/2]).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
start() -> gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
stop() -> gen_server:call(?MODULE, stop).
new_account(Who) -> gen_server:call(?MODULE, {new, Who}).
deposit(Who, Amount) -> gen_server:call(?MODULE, {add, Who, Amount}).
withdraw(Who, Amount) -> gen_server:call(?MODULE, {remove, Who, Amount}).
init([]) -> {ok, ets:new(?MODULE, [])}.
handle_call({new, Who}, _From, Tab) ->
Reply = case ets:lookup(Tab, Who) of
[] -> ets:insert(Tab, {Who, 0}),
{welcome, Who};
[_] -> {Who, you_already_ard_customer}
end,
{reply, Reply, Tab};
handle_call({add, Who, X}, _From, Tab) ->
Reply = case ets:lookup(Tab, Who) of
[] -> not_a_customer;
[{Who, Balance}] ->
NewBalance = Balance + X,
ets:insert(Tab, {Who, NewBalance}),
{thanks, Who, your_balance_is, NewBalance}
end,
{reply, Reply, Tab};
handle_call({remove, Who, X}, _From, Tab) ->
Reply = case ets:lookup(Tab, Who) of
[] -> not_a_customer;
[{Who, Balance}] when X=< Balance ->
NewBalance = Balance - X,
ets:insert(Tab, {Who, NewBalance}),
{thanks, Who, your_balance_is, NewBalance};
[{Who, Balance}] ->
{sorry, Who, your_only_have, Balance, in_the_bank}
end,
{reply, Reply, Tab};
handle_call(stop, _From, Tab) ->
{stop, normal, stopped, Tab}.
handle_cast(_Msg, State) -> {noreply, State}.
handle_info(_Info, State) -> {noreply, State}.
terminate(_Reason, _State) -> ok.
code_change(_OldVsn, State, _Extra) -> {ok, State}.
模块各个功能测试如下
1.开启服务器
c(my_bank).
{ok,my_bank}
my_bank:start().
{ok,<0.92.0>}
2.往账户存钱(因为没有账户所以返回 not_a_customer )
3> my_bank:deposit("ydq", 20).
not_a_customer
3.创建账户
4> my_bank:new_account(ydq).
{welcome,ydq}
4.现在我们再向账户存钱
6> my_bank:deposit(ydq, 20).
{thanks,ydq,your_balance_is,20}
5.取钱(如果超过账户现有的金额那么就会报错)
7> my_bank:withdraw(ydq, 30).
{sorry,ydq,your_only_have,20,in_the_bank}
8> my_bank:withdraw(ydq, 10).
{thanks,ydq,your_balance_is,10}