基本的Erlang问题

时间:2010-12-18 12:46:07

标签: erlang

我一直在努力学习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是一个接受零参数的函数时。我对他在这里要做的事感到困惑。

3 个答案:

答案 0 :(得分:5)

在这篇博客文章(列表)中,您可以看到另外一个函数(start / 2)带有两个参数:

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

您引用的代码示例仅是为简单起见省略此函数的摘录。

答案 1 :(得分:3)

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

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

答案 2 :(得分:1)

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

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