2016-06-21 173 views
3

我正在學習Elixir,並且看不到優於ol開關盒的模式匹配的優勢。我錯過了什麼?模式匹配:優於開關情況?

+0

不同的語言,相同的問題:http://stackoverflow.com/questions/21355060/what-is-the-advantage-of-using-scala-pattern-matching-instead-of-java-switch-cas – JJJ

回答

6

總之,Elixir的模式匹配case將使您的專注於您的數據形狀。不要只考慮語言中的任何表達方式,並尋找真實的條件,而是向讀者展示數據中需要考慮的重要因素。這是更多的意圖揭示。

Elixir有casecond。前者需要一個值並在其上運行不同的模式匹配。後者不會帶來價值,而是會對某些表達式進行評估,直到找到真正的表達式。 A 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非常靈活,但它也是一種代碼味道。有沒有連貫性到塊。表達式可以有副作用。我需要仔細查看cond而不是case

相比之下,case表達式讓我非常明確地瞭解我的數據的形狀。所有的匹配都是在相同的數據上完成的,所以它具有自然的凝聚力。它告訴讀者很多關於作者對某些數據的期望。這是非常意圖顯示。它很快顯示了作者期望數據採取的形狀,以及應該區別對待的任何特殊情況。在閱讀case聲明時,您也可以專注於數據。

模式匹配還可以讓您捕獲模式的一部分。我捕獲匹配模式中的第二個和第三個列表元素。他們只在case區塊內可用,不會「泄漏」。

模式匹配中允許的受限制的表達式集合也意味着它通常非常快。

0

case語句實際上是模式匹配。 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 

現在,也許你打算問一下,在多個函數頭上使用case的優點是什麼?

在這種情況下,它是一種風格/偏好。但是,它確實減少了您的功能的大小。我更喜歡多功能原因的方法,特別是如果每​​個代碼塊很大。