模式匹配:优于开关盒?

时间:2016-06-21 22:13:34

标签: pattern-matching elixir

我正在学习Elixir,并且无法看到模式匹配相对于良好的ol'开关盒。我错过了什么?

2 个答案:

答案 0 :(得分:7)

简而言之,Elixir的模式匹配case将使您专注于数据的形状。您不必在语言中使用任何表达式,并寻找真实条件,而是向读者展示数据中需要考虑的重要形状。这更有意思揭示。

Elixir同时拥有casecond。前者获取一个值并在其上运行不同的模式匹配。后者没有取值,但会改为评估一些表达式,直到找到一个真实的表达式。 cond的作用类似于if … elseif … else

list = [3,2,1]
string = "abc"

case list do
  []        -> :empty             # won't match
  [1 | t]   -> :starts_with_one   # won't match
  [3, b, c] -> "3, #{b} and #{c}" # match!
  _         -> :fallback          # _ would match anything
end

cond do
  List.last(list) == 2     -> :two_at_the_end # false
  length(string) == 3      -> :three_letters  # true
  true                     -> :fallback
end

如您所见,cond中与表达式无关。他们不必对相同的数据采取行动。您还可以使用模式匹配中不允许的表达式。这两个方面都使cond非常灵活,但它也是一种代码味道。该块有 no coherence 。表达式可以有副作用。我需要更仔细地查看cond而不是case

相比之下,case表达式让我非常清楚地了解了数据的形状。所有匹配都在相同的数据上完成,因此它具有自然的内聚力。它告诉读者很多关于作者对某些数据的期望。它非常意图揭示。它可以快速显示作者期望数据采取的形状,以及应该区别对待的任何特殊情况。阅读case语句时,您也可以专注于数据。

模式匹配还可以捕获模式的一部分。我捕获匹配模式中的第二个和第三个列表元素。它们仅在case块内可用,并且不会泄漏"泄漏"进行。

模式匹配中允许的一组受限表达式也意味着它通常非常快。

答案 1 :(得分:0)

案例陈述实际上是模式匹配。 case语句中的每个匹配都是匹配的,可用于提取匹配的片段。此外,它支持警卫。例如:

case my_map do
  %{type: 1, data_for_1: data} -> "Data 1 is %{data}"
  %{type: 2, data_for_2: data} => "Data 2 is %{data}"
  map -> "No matching type found: %{inspect map}"
end

现在,也许你想问一下,在多个功能头上使用案例有什么好处?

在这种情况下,它是风格/偏好的问题。但是,它确实减小了功能的大小。我更喜欢多功能原因方法,特别是如果每​​个代码块都很大。