首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >新手问题-在编程erlang时,应该使用ifs还是短函数?

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

Stack Overflow用户
提问于 2011-03-08 16:22:32
回答 2查看 331关注 0票数 4

我最近开始认真学习Erlang编程一书,我有一个问题。下面是Erlang的正确方法吗?这是ch4对环问题的解决方案(为简洁起见(无退出消息),在基本验证后删除了日志)。进程在传递预期次数的消息后退出;第一个进程等待最后一条消息到达它,然后退出。

除了对风格和实质的一般性批评之外,你能告诉我像这样编写特殊的1-2行函数是否是正确的风格,或者是否应该使用if-s,cases s等?

代码语言:javascript
复制
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.
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-03-08 17:29:52

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

一些评论(个人喜好的问题):

  • Start环可以重写为:

当M< N,N> 0,M>0时start_ring( M,N,Message )产生( ->,run_ring,M,N,Message,0)。

如果使用不当,它将崩溃并出现function_clause错误。在处理错误返回时有一个很好的习惯,如果用户可以对错误做一些合理的处理,例如返回{error, Reason},否则就会崩溃。我认为在这种情况下,直接崩溃是安全的,因为任何其他输入都将是program.

  • run_ring/4 +loop_ring/4中的错误:我不喜欢在包含多个子句的函数之间使用换行符。这使得看清函数的开始和结束变得更加困难。然后可以将注释放在子句主体内,而不是放在子句主体之外。现在识别函数头变得更容易了(并将函数看作一个单元):

run_ring(M,1,Message,Pid) when is_pid(Pid) -> %最后一个连接环的进程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 -一个进程的特例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 (也可以在第一个子句中使用它们,它是bonus documentation!)
票数 7
EN

Stack Overflow用户

发布于 2011-03-08 21:06:23

根据Erlang best practices,人们应该避免ifcase嵌套两次以上:

嵌套代码是在其他case/if/receive语句中包含case/if/receive语句的代码。编写深度嵌套的代码是糟糕的编程风格-代码有向右漂移的趋势,很快就会变得不可读。尽量将大部分代码限制在最多两级缩进。这可以通过将代码划分为更短的函数来实现。

除此之外,我认为使用if/case或简单的模式匹配只是一个品味问题。就我个人而言,我更喜欢使用模式匹配,而不是if或case。所以,如果你问我,你的做法是对的。

关于ifcase,通常您可以将前者重写为后者。有人说:

“总是使用大小写,if结构有点问题”。

嗯,这两个结构的工作方式非常不同。在if构造中计算的表达式是一个guard,它有很多限制- -因为你不能对guard有副作用,它的计算与-的分支无关。case构造没有这个“限制”。您可以在其中使用任何表达式,其结果将与构成案例的模式进行匹配。

可能的重复项:

Erlang style - case vs function pattern matching

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5229997

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档