2014-02-12 48 views
0

我現在在Erlang做實驗,這是我第一次寫Erlang。我有一個initial_state函數應該爲聊天程序中的客戶端設置初始狀態。但是如果你沒有任何東西來存儲它,像Java或C中那樣,那麼設置這個初始狀態又有什麼意義呢?我的意思是感覺就像我剛剛創建初始狀態,然後扔掉它。那是什麼意思?我想在某個地方存儲它,以便以後使用它。Erlang,爲什麼它沒有全局變量和記錄?

initial_state(Nick,GUIName) - > #cl_st {gui = GUIName}。

+2

你有沒有試着問這樣的問題之前閱讀任何教程? –

+0

將狀態傳遞給需要它的所有事物。這在Java/C中也是很好的做法。 –

回答

1

你的問題缺乏一些上下文,讓整個模塊給出一個好的答案可能是有用的。

無論如何,你所顯示的功能是相當簡單的,它是一個返回客戶端狀態記錄的函數,其中的字段gui等於GUIName。

該函數看起來很奇怪,因爲它有2個參數,並且參數Nick未被使用。

在erlang中只有局部變量,它們屬於一個進程,不能與另一個進程共享。這意味着兩件事:

  • 如果你想跟蹤一個變量的值,它所屬的進程不能死,所以它必須是遞歸的。
  • 如果你想進程之間的交換必須使用信息

這是通常的服務器分割成一個初始化函數,一些回調和接口功能和無限循環。我想這是對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}. 

(它必須有錯誤的代碼,我甚至沒有編譯)

相關問題