【问题标题】:Erlang receive loop - variable unbound issueErlang接收循环 - 变量未绑定问题
【发布时间】:2013-04-15 05:23:11
【问题描述】:

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

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

【问题讨论】:

    标签: erlang variable-assignment


    【解决方案1】:

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

    【讨论】:

      猜你喜欢
      • 2016-11-19
      • 2016-06-14
      • 2018-02-25
      • 1970-01-01
      • 2020-11-18
      • 2010-10-18
      • 1970-01-01
      • 2010-12-13
      相关资源
      最近更新 更多