Erlang变量模式匹配

时间:2013-08-14 04:59:04

标签: sockets erlang pattern-matching sockjs

我在一个简单的聊天应用程序中有一个service_echo函数,它使用SockJS实现多用户私聊。我为在线用户列表创建了一个ETS表。通过存储SockJS会话,我想在每次收到来自不同Connection的消息时都向该Connection发送消息。

这是我的service_echo代码。

service_echo(Conn, {recv, Data}, state) ->
    Obj = mochijson2:decode(Data),
    {struct, JsonData} = Obj,
    Name = proplists:get_value(<<"name">>, JsonData),
    A = ets:lookup(username,Name),
    io:format("~p",[Conn]),
    if
      length(A) =:= 0 ->
          ets:insert(username,{Name,Conn});
      true ->
          [{AA,BB}] = ets:lookup(username,Name),

          BB:send(Data)
    end,

     io:format("hello");

即使Conn和BB相同,仍然Conn:send(data)向浏览器发送有效数据,而BB:send(Data)什么也不做,甚至没有显示错误。 由于我是Erlang的新手,请原谅我任何无意义的错误。

1 个答案:

答案 0 :(得分:1)

首先,我建议你永远不要使用length(A) =:= 0来测试列表A是否为空;如果A长列表,计算其元素将花费你很多,虽然结果实际上不会被使用。使用A =:= []代替,更简单,更好。

我不明白为什么你说ConnBB是一样的。这不符合您在此处发布的代码。如果表中没有Name,则插入条目{Name, Conn}。否则,如果表中存在Name并且与单个对象BB相关,则假设此BB是一个模块,并且您调用其中定义的send函数。

可能是你读错了if的语义 - 如果是这样的话,不要让true后卫混淆你,这就是if-then- else是用Erlang编写的。也许你想要有类似的东西:

    ...
    A = ets:lookup(username,Name),
    if
      A =:= [] ->
        ets:insert(username,{Name,Conn})
    end,
    [{_,BB}] = ets:lookup(username,Name),
    BB:send(Data)
    ...

甚至更好:

    ...
    A = ets:lookup(T,Name),
    if
      A =:= [] ->
        ets:insert(T,{Name,Conn}),
        BB = Conn;
      true ->
        [{_,BB}] = A
    end,
    BB:send(Data)
    ...

另一方面,可能是我误解了你想要做的事情。如果是这种情况,请澄清。