Coding style Erlang风格-案例与函数模式匹配

Coding style Erlang风格-案例与函数模式匹配,coding-style,erlang,Coding Style,Erlang,我现在已经到了编写大量Erlang代码的阶段,我可以看到一些风格(好的或坏的)逐渐进入我的编写方式。我想对这个特殊的习语发表一些看法——将case样式的语句转换为函数模式匹配是否更好(可读性更好/更快/无论什么) 例如 比较(人为的例子) 与 。。。 Maybechange仓库(尺寸、类型) ... 当大小>10000-> 某物 当尺寸 有些东西; 可能会更改存储(,)-> 忽略它。 在大多数情况下,我更喜欢后者,但我对其他观点感兴趣。至于我,第一种风格更清晰,可能更快。但它需要测试才能准确地

我现在已经到了编写大量Erlang代码的阶段,我可以看到一些风格(好的或坏的)逐渐进入我的编写方式。我想对这个特殊的习语发表一些看法——将case样式的语句转换为函数模式匹配是否更好(可读性更好/更快/无论什么)

例如

比较(人为的例子)

。。。
Maybechange仓库(尺寸、类型)
...
当大小>10000->
某物
当尺寸<10000->
有些东西;
可能会更改存储(,)->
忽略它。

在大多数情况下,我更喜欢后者,但我对其他观点感兴趣。

至于我,第一种风格更清晰,可能更快。但它需要测试才能准确地说出来。
在第二种情况下,如果输入=然后,将对“大小>10000”和“大小<10000”进行评估。

您可以通过以下操作使这些示例更加相似:

case Type of
   ets  when Size > 10000 -> ...;
   dets when Size < 10000 -> ...;
   _ -> ...
end.
案例类型
当尺寸>10000->时的ets。。。;
当尺寸<10000->时检测。。。;
_ -> ...
结束。
这对我来说似乎更清楚。将其拆分为单独函数的优点是,您可以为其指定一个名称,该名称用作文档并显示在堆栈跟踪中。如果这个片段是一个更大的函数的一部分,我会把它分离出来,否则就没问题了


值得考虑的一点是,在编写错误案例时,函数将接受ets/dets以外的类型参数。除非这是您真正想要的,否则值得对该条款进行更严格的限制。

第二种方法是首选方法,尤其是如果您可以将条款保留在一行:

maybeCngStor(Sz, ets)  when Sz > 10000 -> something;
maybeCngStor(Sz, dets) when Sz < 10000 -> somethingelse;
maybeCngStor(_,_)                      -> ignoreit.
当您在下一个圣诞节从10000英尺的高空跳伞到函数中寻找bug时,这将为您提供简短的变量名。F显然是一个Foo,等等…

(作为一个答案来获取代码的格式…!)

我在做一些改变时发现的一件事是 这种方法可以改变默认短路。例如

case A > 10 of 
      true -> 
             case B > 10 of 
                  true -> dummy1; 
                  false -> dummy2 
             end; 
      false -> dummy3 
end 
如果你像这样调用它,就必须始终执行B>10

doTest(A > 10, B > 10) 
什么时候


这有时不是你想要的

如果在函数中首先要做的事情是打开一个case子句,那么最好将这个顶级子句转换为函数模式匹配。

在何时选择
case
以及何时使用
函数
上有一个选项。提到两件事:

  • 它们在VM中以相同的方式表示,因此这两个解决方案在性能上没有差异

  • 如果您需要针对多个参数使用防护措施,那么使用函数可能会更好


  • 总而言之,这主要是一个风格和品味的问题。

    当大小<10000->应该是大小时,可能会更改存储(大小,dets)。使用uu作为一个通用子句对我来说也总是有一种不好的味道-我通常会忽略它,让模式匹配将其丢弃。但在这种特殊情况下,如果它不匹配,我什么也不想做。我喜欢在case子句中加入警卫的替代方法……是的,我从内存中编写了片段,因此逻辑可能有点不正确。关于第一种样式,我喜欢的一件事是神奇地构造一个元组来进行模式匹配——我以前用过类似于{Test1,Test2,Test3,Test4}的东西,然后为我真正感兴趣的特定组合使用了一整套case子句。它胜过了一整套嵌套的if语句!担心测试变量大小的成本是微观优化。编写尽可能清晰的代码,当您根据测试发现此构造的特定实例速度太慢时,然后并且只有在之后才更改它。在大多数情况下,我非常喜欢函数匹配。虽然对我来说,这个循环通常是这样的:先写案例陈述。稍后重构为函数。我倾向于先编写代码,然后进行重构。我越接近一条直线,我就越快乐。
    maybeCngStor(Sz, ets)  when Sz > 10000 -> something;
    maybeCngStor(Sz, dets) when Sz < 10000 -> somethingelse();
    maybeCngStor(_,_)                      -> ignoreit.
    
    somethingelse() ->
       (...)
       Return.
    
    #record{foo = F, bar = B, baz = Bz} = Parameter
    
    case A > 10 of 
          true -> 
                 case B > 10 of 
                      true -> dummy1; 
                      false -> dummy2 
                 end; 
          false -> dummy3 
    end 
    
    doTest(A > 10, B > 10) 
    
    doTest(true, true) -> dummy1; 
    doTest(true, false) -> dummy2; 
    doTest(false, _) -> dummy3.