代码之家  ›  专栏  ›  技术社区  ›  nmichaels

过程字典在这种情况下合适吗?

  •  7
  • nmichaels  · 技术社区  · 14 年前

    我在这里和其他地方读过一些评论,认为Erlang的过程字典是个坏主意,应该死。一般来说,作为一个完全的二郎新手,我会尽量避免。不过,在这种情况下,我的其他选择并不好。

    我有一个主dispatcher函数,如下所示:

    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.
    

    很明显,我的名字对我来说更有意义,但这就是它的要点。在dou cmd2_stuff()调用的函数调用的函数中,我想向所有用户发送消息,告诉他们我所做的事情。为了做到这一点,我需要从我发送消息的地方获取用户列表。用户列表不容易保持全局状态,因为它只是一个数据结构,表示我操作的唯一数据块。

    或者,我可以把所有的 do_cmdN_stuff() 函数返回要发送的消息。不过,这也不太好,因为发送消息可能不是我最不想做的事情,而且它会把我的调度员和一堆 {Msg, NewState} 元组。此外,有些函数在某些时候可能没有任何消息可以发送。

    就像我之前说的,我对埃兰很陌生。也许有经验的人能给我指一个更好的方法。有吗?过程字典在这种情况下合适吗?

    6 回复  |  直到 14 年前
        1
  •  4
  •   I GIVE TERRIBLE ADVICE    14 年前

    一般规则是,如果您有疑问,您不应该使用过程字典。

    Pid ! {forward, Msg}
    

    哪里 Pid 将负责将所有内容发送到一系列其他进程。现在,您仍然需要传递Pid,除非您在某个注册表中为它指定一个名称来查找它。或者用 register/2 , global gproc

        2
  •  4
  •   Zed    14 年前

    一个简单的答案是将全局数据嵌套在一个状态记录中,然后该状态记录将在系统中穿行,至少在停止级别。这使得在将来向状态添加新字段变得很容易,而且这种情况并不少见,并且允许您保持全局状态数据结构不变。所以最初

    -record(state, {users=[],state_data}).
    

    将它定义为一个记录可以方便地在必要时进行访问和扩展。

        3
  •  1
  •   Peer Stritzinger    14 年前

    如果你不想这样做,就把它放在状态。对于计算的这一部分(也包含用户列表),可以有一个特殊的状态。

    具体做什么是很难推荐的,因为这在很大程度上取决于您的确切应用程序和偏好。

    只需从提到的可能性中选择,就好像进程字典不存在一样。也许您的代码需要重新构造如果没有一个变体看起来很优雅,那么没有流程字典总有更好的方法。

    很糟糕的是,它仍然存在,因为它吸引了很多最初的Erlang用户。

        4
  •  1
  •   Hynek -Pichi- Vychodil Paulo Suassuna    14 年前

    你真的不应该使用进程字典。只有在下列情况下我才接受使用词典

    1. 我可以完全控制从生成到终止的过程,也就是说,我使用最小的已知外部模块集。

    广告1。不是您的情况,您正在服务器中使用。广告2。我不知道是不是你的案子。公元3年。不是您的情况,因为您需要收件人列表,这样您就不会从该过程中获得任何好处字典是非常快速的键/值存储。就你而言,我看不出你为什么不把你需要的东西包括在 State 国家

        5
  •  1
  •   Lii bob    5 年前

    这是一个有趣的问题,因为它涉及到功能设计的基本原理。

    我的意见:

    如果这是不可能的,传递接收器作为参数,即使它有点混乱。如果广播函数使用该数据,则应显式地将其提供给它,以使其清晰和可预测。

    使用ETS作为同行Stritzinger的建议实际上并不比PD好多少,两者都隐藏了这样一个事实:广播功能使用接收器列表,并使其依赖于全局数据。

    把我的调度员弄得乱七八糟 属于{Msg,NewState}

    这也是我的经验,你经常这样结束。它不是特别漂亮,但功能设计似乎鼓励了这一点。是否可以引入一些语言功能,使其更美丽和自然?

    编辑:

    6年前我写道:

    是否可以引入一些语言功能,使其更美丽和自然?

    在学习了更多关于函数式编程的知识之后,我意识到这方面的例子是状态单子和 do-notation

        6
  •  0
  •   Dimagog    8 年前

    我会考虑给 self() 从调用堆栈的深层,并在顶层处理它 dispatch