我最近认真研究了Erlang编程,我有一个问题.以下是Erlang的正确方法吗?这是(为了简洁而修改(没有退出消息),在基本验证后删除了日志)从ch4解决了环问题.进程在传递预期的消息次数后退出; 第一个进程等待最后一条消息到达并退出.
除了对风格和内容的一般批评外,你能否告诉我,如果写这样一个特殊的1-2行函数是正确的风格,还是应该使用if-s,case-s等?
start_ring( 0, _, _ ) -> {error, badarg};
start_ring( _, 0, _ ) -> {error, badarg};
start_ring( M, N, Message ) ->
spawn( ring, run_ring, [M, N, Message, 0] ).
% last process that connects the ring
run_ring( M, 1, Message, Pid ) when is_pid(Pid) ->
loop_ring( M, Message, Pid, false );
% process in the middle
run_ring( M, N, Message, Pid ) when is_pid(Pid) ->
loop_ring( M, Message, spawn( ring, run_ring, [M, N-1, Message, Pid] ), false );
% first process - special case for one process
run_ring( M, 1, Message, _ ) ->
loop_ring( M, self() ! Message, self(), true );
% first process
run_ring( M, N, Message, _ ) ->
NextPid = spawn( ring, run_ring, [M, N-1, Message, self()] ),
loop_ring( M, NextPid ! Message, NextPid, true ).
loop_ring( 0, _, _, _ ) -> ok;
loop_ring( 1, Message, Next, true ) -> ok;
loop_ring( M, Message, Next, IsMaster ) ->
receive
Message -> loop_ring( M - 1, Next ! Message, Next, IsMaster )
end.
Run Code Online (Sandbox Code Playgroud)
我觉得你的风格很简洁!干得好!
一些评论(个人品味):
开始响铃可以改写为:
start_ring( M, N, Message ) when M < N, N > 0, M > 0 ->
spawn( ring, run_ring, [M, N, Message, 0] ).
Run Code Online (Sandbox Code Playgroud)
function_clause如果使用不当,这将导致错误.处理错误返回时有一个好习惯,如果用户可以对错误做一些合理的事情,例如返回{error, Reason},否则只是崩溃.我认为在这种情况下,崩溃是安全的,因为任何其他输入都是程序中的错误.
run_ring/4+ loop_ring/4:我不喜欢在具有多个子句的函数之间使用换行符.这使得更难以看到函数的开始和结束位置.然后可以将注释放在子句体内而不是外部.现在识别函数头更容易(并将函数看作一个单元):
run_ring(M, 1, Message, Pid) when is_pid(Pid) ->
% last process that connects the ring
loop_ring(M, Message, Pid, false);
run_ring(M, N, Message, Pid) when is_pid(Pid) ->
% process in the middle
loop_ring(M, Message, spawn(ring, run_ring, [M, N-1, Message, Pid]), false);
run_ring(M, 1, Message, _) ->
% first process - special case for one process
loop_ring(M, self() ! Message, self(), true);
run_ring(M, N, Message, _) ->
% first process
NextPid = spawn(ring, run_ring, [M, N-1, Message, self()]),
loop_ring(M, NextPid ! Message, NextPid, true).
Run Code Online (Sandbox Code Playgroud)我个人不喜欢括号内的空格(正如我所说,个人品味).:-)使代码更"蓬松".
除非您知道自己不想要它spawn_link/3,spawn/3否则请使用.在开发程序时,它可以更容易地检测错误等.
loop_ring/4发出编译器警告的第二个子句.使用_Message而_Next不是(将它们用于第一个条款,它是奖金文档!)