我现在正在Erlang做一个实验室,这是我第一次写Erlang。我有一个initial_state函数,它应该在聊天程序中为客户端设置初始状态。但是如果你没有像Java或C那样存储它的东西,那么设置这个初始状态有什么意义呢?我的意思是感觉我只是在创建初始状态然后把它扔掉。那有什么意义呢?我想在某处存放它以便以后可以使用它。
initial_state(Nick,GUIName) - > #cl_st {gui = GUIName}。
答案 0 :(得分:2)
你的问题缺乏一些背景,让整个模块给出一个好的答案可能是有用的。
无论如何,你展示的功能非常简单,它是一个返回客户端状态记录的函数,字段gui等于GUIName。
这个函数看起来很奇怪,因为它有2个参数,参数Nick未使用。
在erlang中只有局部变量,它们属于一个进程,不能与另一个进程共享。这意味着两件事:
通常将服务器拆分为init函数,一些回调和接口函数以及无限循环。我想这是对OTP的gen_server行为的一个很好的介绍。我可以想象以这种方式补充你的代码:
%% the record state definition, it will include
%% the client nickname,
%% the gui name (or pid ?)
%% the client cart with a default value equals to the empty list
-record(cl_st,{nick,gui,cart=[]}).
initial_state(Nick, GUIName) ->
%% the role of this function could be to start processes such as the gui
%% and return the initial state
%% add some code to start the gui
#cl_st { gui = GUIName, nick = Nick}.
%% an example of an interface function to add some item to the client cart
%% it simply pack the parameters into a tuple and send it to the server
%% Note that the server is identified by its pid, so somwhere there must be a unique
%% server that keep the list of all clients and their server pid
add_to_cart(Pid,Item,Price,Quantity) ->
Pid ! {add_to_cart,Item,Price,Quantity}.
%% this function calls the init function, starts the server in a new process (usage of spawn) with the
%% initial state and returns the server pid
start(Nick,GUIName) ->
State = initial_state(Nick, GUIName),
spawn(?MODULE,cl_loop,[State]).
stop(Pid) ->
Pid ! stop.
%% the server loop
%% this example manages 2 kind of messages
cl_loop(State) ->
receive
%% add to cart simply builds a tuple made of item, price and quantity and add it to a list
%% of tuple representing the cart content.
%% it calls itself recursively with a new state as parameter where the old cart
%% is replaced by the new one
{add_to_cart,Item,Price,Quantity} ->
NewCart = [{Item,Price,Quantity}|State#cl_st.cart],
cl_loop(State#cl_st{cart=NewCart});
%% to stop the server, it calls the terminate callback function and does not call itself recursively
stop ->
terminate(State);
%% other messages are ignored, the server simply calls itself with an unchanged state
Ignored ->
cl_loop(State)
end.
%% a callback function to terminate the server properly
terminate(State#cl_st{gui = GUIName, nick = Nick}) ->
%% some code to stop the gui
{stopped_client, Nick}.
(它必须在代码中出错,我甚至没有编译它)