2013-04-14 34 views
1

所以我需要編寫這個函數,它接收來自三個不同進程的數字並保存它們。我無法讓它工作,我得到了「可變的未綁定」錯誤。Erlang接收循環 - 變量未綁定問題

serverB2(Time, Client1, Client2, Client3) -> 
    receive 
     {From, TimeClient} -> 
      if 
       From == Client1 -> 
        TimeClient1 = TimeClient; 
       From == Client2 -> 
        TimeClient2 = TimeClient; 
       From == Client3 -> 
        TimeClient3 = TimeClient; 
      end, 
      serverB2(Time, Client1, Client2, Client3) 
    end, 
List = [Time, TimeClient1, TimeClient2, TimeClient3], 
io:format("~w \n", List). 

回答

1

你得到變量綁定錯誤,因爲你的代碼有三個路徑,並在每個路徑中,就只綁定變量TimeClient1TimeClient2一個TimeClient3,所以你總是有他們兩個綁定。更糟的是你的代碼永遠不會停止。您將收到消息,然後評估如果聲明,然後遞歸調用serverB2代碼並一次又一次。接收後,您的語句沒有任何代碼路徑。

我會以這種方式

serverB2(Time, Client1, Client2, Client3) -> 
    List = [ Time 
     | [ receive {Client, TimeClient} -> TimeClient end 
     || Client <- [Client1, Client2, Client3]]], 
    io:format("~w~n", [List]). 

或該是多麼列表理解上面會被編譯器翻譯更傳統的方式

serverB2(Time, Client1, Client2, Client3) -> 
    List = [ Time | collect_times([Client1, Client2, Client3])], 
    io:format("~w~n", [List]). 

collect_times([]) -> []; 
collect_times([Client|Tail]) -> 
    TimeClient = receive {Client, Time} -> Time end, 
    [ TimeClient | collect_times(Tail) ]. 

寫這篇文章。

我在這裏使用的訣竅是,我按順序接收消息,而不是他們到達郵箱的順序。我在那裏使用選擇性接收,因爲在上述兩個示例中變量Client都被綁定爲接收模式。如何接收消息以獲取消息的方式比較複雜,因此只能以非常好的理由(例如性能)使用消息。