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