为什么 if 语句中的模式匹配不受欢迎?
Why is pattern matching in an if statement frowned upon?
我刚刚在我的 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 给出的信息是:
There should be no matches in if
conditions.
换句话说 if error = form.errors[field] do
中有模式匹配。但是,除了该消息之外,Credo 库没有详细说明。
为什么这么糟糕?
这并没有那么糟糕,但通常 if
表达式不那么地道。 case
和 cond
之类的替代方案更强大,可以更明确地说明发生的事情,并可以导致更可预测的行为。可能有一些情况(比如这个)这段代码没问题,我不知道与其他情况相比分析这种情况会有多容易。这个表达式,例如,returns nil 当没有错误时......这并不像处理 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
更强大、简洁并帮助你推理并为意外行为设置代码(上面代码中的下划线,if get_status
是一个获取特定服务状态的函数,我们期望类似 :ok 的服务准备就绪和 :not_ok 如果服务没有准备好,那么如果服务的机器挂了怎么办?或者我们的网线断开了?)。
当然这可以通过多个 if
语句来实现,但这会导致糟糕的代码可读性或可维护性不佳。
我刚刚在我的 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 给出的信息是:
There should be no matches in
if
conditions.
换句话说 if error = form.errors[field] do
中有模式匹配。但是,除了该消息之外,Credo 库没有详细说明。
为什么这么糟糕?
这并没有那么糟糕,但通常 if
表达式不那么地道。 case
和 cond
之类的替代方案更强大,可以更明确地说明发生的事情,并可以导致更可预测的行为。可能有一些情况(比如这个)这段代码没问题,我不知道与其他情况相比分析这种情况会有多容易。这个表达式,例如,returns nil 当没有错误时......这并不像处理 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
更强大、简洁并帮助你推理并为意外行为设置代码(上面代码中的下划线,if get_status
是一个获取特定服务状态的函数,我们期望类似 :ok 的服务准备就绪和 :not_ok 如果服务没有准备好,那么如果服务的机器挂了怎么办?或者我们的网线断开了?)。
当然这可以通过多个 if
语句来实现,但这会导致糟糕的代码可读性或可维护性不佳。