为什么if语句中的模式匹配不受欢迎?

时间:2016-02-13 00:51:54

标签: elixir phoenix-framework

我刚刚在我的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库还没有详细说明。

为什么这么糟糕?

2 个答案:

答案 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表达不那么惯用。像casecond这样的替代方案功能更强大,可以更明确地说明发生了什么,并且可以导致更可预测的行为。可能有一些情况(比如这个)这个代码很好,我不知道分析这个案例与其他案例相比是多么容易。例如,当没有错误时,这个表达式返回nil ...这并不像处理2个case并提供空字符串一样明确。