【问题标题】:Basic Erlang Question基本 Erlang 问题
【发布时间】:2011-05-27 13:22:24
【问题描述】:

我一直在尝试学习 Erlang,偶然发现了一些由 Joe Armstrong 编写的代码:

start() ->
    F = fun interact/2,
    spawn(fun() -> start(F, 0) end).

interact(Browser, State) ->
    receive
        {browser, Browser, Str} ->
            Str1 = lists:reverse(Str),
            Browser ! {send, "out ! " ++ Str1},
            interact(Browser, State);
    after 100 ->
        Browser ! {send, "clock ! tick " ++ integer_to_list(State)},
        interact(Browser, State+1)
end.

来自一篇关于在 Erlang 中使用 websockets 的博文:http://armstrongonsoftware.blogspot.com/2009/12/comet-is-dead-long-live-websockets.html

有人可以向我解释一下为什么在 start 函数中,他会生成匿名函数 start(F, 0),而 start 是一个接受零参数的函数。我对他在这里想要做什么感到困惑。

【问题讨论】:

    标签: erlang


    【解决方案1】:

    在 Erlang 中,函数由它们的名称和它们的 arity(它们采用的参数数量)来标识。您可以拥有多个具有相同名称的函数,只要它们都具有不同数量的参数即可。您在上面发布的两个函数是start/0interact/2start/0 不调用自己;相反,它调用start/2,如果您进一步查看链接到的页面,您会发现start/2 的定义。

    以这种方式使用spawn的目的是在后台启动一个服务器进程并将控制权返回给调用者。要使用这段代码,我猜你会启动 Erlang 解释器,加载脚本,然后调用 start/0 函数。然后,此方法将在后台启动一个进程并返回,以便您可以继续输入 Erlang 解释器。

    【讨论】:

      【解决方案2】:

      在这篇博文(列表)的更下方,您可以看到另一个函数 (start/2) 接受两个参数:

      start(F, State0) ->
      {ok, Listen} = gen_tcp:listen(1234, [{packet,0},
                                        {reuseaddr,true},
                                        {active, true}]),
      par_connect(Listen, F, State0).
      

      您引用的代码示例只是一个摘录,为简单起见省略了此函数。

      【讨论】:

        【解决方案3】:

        以这种方式生成fun 的原因是为了避免必须导出仅供内部使用的函数。一个问题是,所有导出的函数都可供所有用户使用,即使它们仅用于内部。其中一个示例是gen_server 的回调模块,它通常包含客户端的导出 API 和 gen_server 行为的回调函数。回调函数仅供gen_server 行为调用,其他人不能调用,但它们在导出列表中可见且不会被阻止。

        生成 fun 会减少导出的内部函数的数量。

        【讨论】:

          猜你喜欢
          • 2021-03-22
          • 2013-01-06
          • 1970-01-01
          • 2011-06-29
          • 2011-09-29
          • 2018-09-22
          • 2010-12-08
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多