新手问题 - 在编写erlang时应该使用ifs还是short函数?

Ser*_*gey 4 erlang

我最近认真研究了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)

Ada*_*erg 7

我觉得你的风格很简洁!干得好!

一些评论(个人品味):

  • 开始响铃可以改写为:

    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不是(将它们用于第一个条款,它是奖金文档!)