Erlang:强制公开方法,为什么?

标签 erlang

我正在阅读 Joe Armstrong 的书 Programming Erlang, 2nd Edition,我们在其中制作了一个文件服务器。

我的代码:

-module(afile_server).
-author("harith").

%% API
-export([start/1]).

start(Dir) ->  spawn(afile_server, loop, [Dir]).

loop(Dir) ->
    receive
        {Client, list_dir}  ->
            Client ! {self(), file:list_dir(Dir)};
        {Client, {get_file, File}}  ->
            File_Path = filename:join(Dir, File),
            Client ! {self(), file:read_file(File_Path)}
    end,
    loop(Dir).

正如我们所见,loop 是一个私有(private)方法,不应该暴露给外界。现在,当我运行它时,我得到:

1> FileServer = afile_server:start(".").
<0.33.0>

=ERROR REPORT==== 3-Jan-2015::06:58:56 ===
Error in process <0.33.0> with exit value: {undef,[{afile_server,loop,["."],[]}]}

2> 

但是当我将 loop 公开为:

-module(afile_server).
-author("harith").

%% API
-export([start/1, loop/1]).

start(Dir) ->  spawn(afile_server, loop, [Dir]).

loop(Dir) ->
    receive
        {Client, list_dir}  ->
            Client ! {self(), file:list_dir(Dir)};
        {Client, {get_file, File}}  ->
            File_Path = filename:join(Dir, File),
            Client ! {self(), file:read_file(File_Path)}
    end,
    loop(Dir).

然后它运行正常:

1> FileServer = afile_server:start(".").
<0.33.0>
2> 

spawn 是否要求方法公开?我想是的,因为它运行为:

afile_server:loop(Dir)  

但我想确保没有其他问题。

最佳答案

如果您将 spawn 与 M:F:A 一起使用,您将被迫将循环设置为公共(public)。

可以这样避免:

-module(afile_server).
-export([start/1]).

start(Dir) ->  spawn(fun() -> loop(Dir) end).

loop(Dir) ->
    receive
        {Client, list_dir}  ->
            Client ! {self(), file:list_dir(Dir)};
        {Client, {get_file, File}}  ->
            File_Path = filename:join(Dir, File),
            Client ! {self(), file:read_file(File_Path)}
    end,
    loop(Dir).

如果您的方法没有参数,您还可以使用:

spawn(fun loop/0),

使用带有 M:F:A 的版本的一个很好的理由在于,每当您加载同一模块的新版本时,都会调用这个新版本。否则你将继续调用旧模块。

关于Erlang:强制公开方法,为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27756213/

相关文章:

erlang - 如何处理 Erlang 中另一个节点的死亡?

macos - Erlang 调试器错误 : Could not find 'wxe_driver.so'

performance - 提高二郎牛仔表现

erlang - Erlang 中的 "new"是官方标准的一部分吗?我们应该使用它吗?

multithreading - Erlang 实现的 Web 服务器的线程池模拟不起作用

erlang - Erlang 的 open_port 调用是否链接到结果进程?

erlang - 执行进程通信

Erlang 脚本参数

concurrency - Erlang消息接收顺序

erlang - 如何优雅地检查 Erlang 中的许多条件?