【问题标题】:Erlang, Matching with list foreachErlang,与列表 foreach 匹配
【发布时间】:2014-04-09 02:25:32
【问题描述】:

我一直在用 Erlang 为一个学校项目制作一个聊天应用程序,但我遇到了一个问题。我试图让我的程序并发,为了做到这一点,我为通道发送的每条消息启动一个新线程。我使用 list:foreach 执行此操作,但我想确保我不会向在频道中输入内容的人发送消息。

request(State, {message, {UserID,UserPID}, Token}) ->
case catch lists:member({UserID,UserPID}, State#channel.users) of
    false ->
        {{error, user_not_joined}, State};
    true -> 
        spawn( fun() ->
        ListOfUsers = State#channel.users,
        UserPIDs = lists:map(fun ({_, V}) -> V end, ListOfUsers),
        %spawn( fun() ->end)
        lists:foreach( 
            fun(UserPID) -> ok end,
            fun(PID) ->
                spawn( fun() -> genserver:request(PID, {message_from_server, State#channel.name, UserID, Token}) end) 
            end, UserPIDs) end),
        {ok, State}
end;

我非常想做的是与 foreach 中的 UserPID 匹配。截至目前,我只收到警告:

channel.erl:39:警告:变量“UserPID”未使用 channel.erl:39:警告:变量 'UserPID' 隐藏在 'fun' 中

第 3 行很有趣(UserPID) -> ok end,

干杯

【问题讨论】:

    标签: erlang


    【解决方案1】:

    legoscia 的回答很好,但我要补充一点,列表理解通常比lists:foreach 更易于使用和阅读。请注意,列表推导能够忽略基于子句的值。考虑以下示例:

    -module(filter).
    
    -export([do/0]).
    
    do() ->
        Values = lists:seq(1,10),
        IgnoreThisValue = 5,
        %% print all values unequal to IgnoreThisValue
        [io:format("Value: ~b~n", [Value]) ||
         Value <- Values, Value =/= IgnoreThisValue],
        ok.
    

    在shell中运行:

    1> make:all([load]).
    Recompile: filter
    up_to_date
    2> filter:do().     
    Value: 1
    Value: 2
    Value: 3
    Value: 4
    Value: 6
    Value: 7
    Value: 8
    Value: 9
    Value: 10
    

    关于您的代码的附注:为什么要为每个进程生成一个线程?我假设您正在使用行为gen_server(如果我错了,请纠正我)。如果是这样,您应该考虑使用cast 函数来简单地发送消息。由于您不检查genserver:request/2 的结果,这可能是一个可行的选择,可以为您节省大量流程。

    【讨论】:

    • 另一种更慢的方法是在遍历之前使用L -- [Pid]从列表中删除Pid。但这会建立一个新列表。
    【解决方案2】:

    由于函数参数隐藏了现有变量,因此您需要为此使用保护:

    fun(PID) when PID =:= UserPID -> ok end
    

    【讨论】:

      猜你喜欢
      • 2012-06-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-10
      • 2016-10-27
      相关资源
      最近更新 更多