我在这里和其他地方读过几条评论,暗示Erlang的流程字典是一个坏主意,应该死掉.通常,作为一个总的Erlang新手,我只是避免它.但是,在这种情况下,我的其他选择并不是很好.
我有一个主调度函数,看起来像这样:
dispatch(State) ->
receive
{cmd1, Params} ->
NewState = do_cmd1_stuff(Params, State),
dispatch(NewState);
{cmd2, Params} ->
NewState = do_cmd2_stuff(Params, State),
dispatch(NewState);
BadMsg ->
log_error(BadMsg),
dispatch(State)
end.
Run Code Online (Sandbox Code Playgroud)
显然,我的名字对我来说更有意义,但这就是它的要点.在由do_cmd2_stuff()调用的函数调用的函数调用的函数中,我想向所有用户发送消息,告诉他们我做过的事情.为此,我需要从发送消息的位置获取用户列表.用户列表不容易粘在全局状态,因为这只是一个数据结构,代表我操作的唯一数据块.
我看到它的方式,除了使用进程字典之外,我还有一些令人不快的选择.我可以将用户列表通过所有不同级别的功能发送到播放广播的最底层.这是令人不愉快的,因为它导致我的所有功能获得一个参数,无论他们是否真的关心它.
或者,我可以让所有do_cmdN_stuff()函数返回要发送的消息.然而,这并不是很好,因为发送消息可能不是我想要做的最后一件事,它使我的调度员与一堆{Msg, NewState}元组混乱.此外,某些功能可能没有任何消息可以发送一些时间.
就像我之前说的那样,我对Erlang很新.也许拥有更多经验的人可以指出我更好的方式.有吗?在这种情况下,流程字典是否合适?
一般规则是,如果您有疑问,则不应使用流程字典。
如果您提到的两个选项不够好(我个人喜欢您返回要发送的消息的选项)并且您想要的是一些特定的代码来跟踪用户并向他们转发消息,也许您想要做的有一个保存该信息的进程。
Pid ! {forward, Msg}
Run Code Online (Sandbox Code Playgroud)
wherePid将负责将所有内容发送到一堆其他进程。现在,您仍然需要传递 Pid,除非您在某个注册表中给它一个名称来查找它。要么与register/2,global要么gproc。