我刚刚在我的Phoenix应用中安装了Credo混合库,它告诉我web/views/error_helpers.ex
文件在错误标记方法中有重构机会:
def error_tag(form, field) do
if error = form.errors[field] do
content_tag :span, translate_error(error), class: "help-block"
end
end
Credo给出的信息是:
在
if
条件下应该没有匹配项。
换句话说,if error = form.errors[field] do
中有一个模式匹配。但是,除了那条消息之外,Credo库还没有详细说明。
为什么这么糟糕?
答案 0 :(得分:2)
与其他海报一样,它表示它不那么惯用,可能会导致分析时遇到一些麻烦(或者常见的错误,如键入=
而不是==
)。我的主要论点是以下案例:
if get_status = :ok do
# Some code
else
# Some other code
这是非常有限并且不具有表现力,cond do
您可以执行以下操作:
cond get_status do
:ok -> # Some code
:not_ok -> # Some other code
_ -> # More code
end
如果条件几乎是二元的,你可以得到A或得到别的东西。如果结果是来自本地函数调用或类似的布尔值,这是很好的,但如果您正在使用分布式系统,从另一台机器或类似机器获取信息,cond do
更强大,更简洁并且可以帮助您解释并为意外行为设置代码(上面代码中的下划线,如果get_status
是一个函数,它获取我们期望的某个服务的状态:ok表示服务正在准备就绪:not_ok如果服务还没准备好,那么如果服务的机器坏了怎么办?或者我们的网线断开了?)。
当然,这可以通过多个if
语句来实现,但这会导致代码不够易读或无法维护。
答案 1 :(得分:1)
这并不是很糟糕,但通常if
表达不那么惯用。像case
和cond
这样的替代方案功能更强大,可以更明确地说明发生了什么,并且可以导致更可预测的行为。可能有一些情况(比如这个)这个代码很好,我不知道分析这个案例与其他案例相比是多么容易。例如,当没有错误时,这个表达式返回nil ...这并不像处理2个case并提供空字符串一样明确。