gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-04 22:51:14 25 4
gpt4 key购买 nike

最近开始认真学习Programming Erlang这本书,有个问题想请教一下。
下面是正确的 Erlang 方法吗?这是(为简洁起见进行了修改(没有退出消息),在基本验证后删除了日志记录)解决 ch4 中的环问题。进程在传递消息预期次数后退出;第一个进程等待最后一条消息到达并退出。

除了对风格和实质的一般批评之外,你能告诉我写这样的特殊 1-2 行函数是否是一种正确的风格,或者是否应该使用 if-s、cases-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.

最佳答案

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

一些评论(个人品味问题):

  • 起始环可以改写为:
    start_ring( M, N, Message ) when M < N, N > 0, M > 0 -> 
    spawn( ring, run_ring, [M, N, Message, 0] ).

    这将与 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).
  • 我个人不喜欢括号内的空格(正如我所说,个人品味)。 :-) 使代码更加“蓬松”。
  • 使用 spawn_link/3而不是 spawn/3除非你知道你不想要它。在开发程序时,它可以更容易地检测错误等。
  • loop_ring/4第二条发出编译器警告。使用 _Message_Next相反(也将它们用于第一个子句,这是额外的文档!)
  • 关于erlang - 新手问题 - 在编程 erlang 时应该使用 ifs 还是短函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5229997/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com