1

所以我需要编写这个函数来接收来自三个不同进程的数字并保存它们。我无法让它工作,我收到“变量未绑定”错误。

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).
4

1 回答 1

1

您收到 variable unbound 错误,因为您的代码具有三个路径,并且在每个路径中您只会绑定一个 variables TimeClient1TimeClient2因此TimeClient3您总是有两个未绑定。更糟糕的是,您的代码永远不会停止。您将收到消息,然后评估 if 语句,然后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在上面的两个示例中变量都绑定在接收模式中。有更复杂的方式如何接收消息,以便它们如何到达,您应该使用非常好的理由(例如性能)。

于 2013-04-14T21:17:37.217 回答