2016-06-21 19 views
3

Ich lerne Elixir, und kann nicht den Vorteil der Mustererkennung über guten alten Schalter Fall sehen. Was vermisse ich?Mustervergleich: Vorteil gegenüber Switch-Case?

+0

Andere Sprache, gleiche Frage: http://stackoverflow.com/questions/21355060/what-ist-the-advantage-of-using-scala-pattern-matching-instead-of-java-switch-cas – JJJ

Antwort

6

Kurz gesagt, Elixirs Muster entspricht case wird Sie konzentrieren sich auf die Form Ihrer Daten. Anstatt nahezu alle Ausdrücke in der Sprache zuzulassen und nach einer echten Bedingung zu suchen, zeigen Sie dem Leser, welche Formen in Ihren Daten wichtig sind. Es ist mehr Absicht enthüllt.

Elixir hat sowohl case als auch cond. Ersteres nimmt einen Wert an und führt verschiedene Musterübereinstimmungen durch. Letzteres nimmt keinen Wert an, sondern wertet stattdessen einige Ausdrücke aus, bis es einen gefunden hat, der truthig ist. A cond funktioniert wie 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 

Wie Sie sehen, gibt es wirklich nichts, was den Ausdruck in cond verbindet. Sie müssen nicht auf die gleichen Daten reagieren. Sie können auch Ausdrücke verwenden, die beim Mustervergleich nicht zulässig sind. Beide Aspekte machen cond sehr flexibel, aber es ist auch irgendwie ein Code-Geruch. Es gibt keine Kohärenz zum Block. Ausdrücke können Nebenwirkungen haben. Ich muss genauer auf eine cond als eine case aussehen.

Im Gegensatz dazu lässt mich die case Ausdruck sehr explizit Grund für die Form meiner Daten. Alle Übereinstimmungen werden mit denselben Daten durchgeführt, so dass sie einen natürlichen Zusammenhalt haben. Es erzählt einem Leser viel über die Erwartungen des Autors an einige Daten. Es ist sehr Absicht enthüllt. Es zeigt schnell die Formen, die der Autor erwartet, die Daten zu nehmen, und alle Sonderfälle, die anders behandelt werden sollten. Wenn Sie eine case Anweisung lesen, können Sie sich auch auf die Daten konzentrieren.

Mit der Mustererkennung können Sie auch Teile des Musters erfassen. Ich erfasse das zweite und dritte Listenelement in dem passenden Muster. Sie sind nur innerhalb des Blocks case verfügbar und "lecken" nicht.

Die eingeschränkte Menge an Ausdrücken, die in einer Musterübereinstimmung erlaubt sind, bedeutet auch, dass sie im Allgemeinen sehr schnell ist.

0

Eine Case-Anweisung ist tatsächlich Mustererkennung. Jede Übereinstimmung in der case-Anweisung ist eine Übereinstimmung und kann zum Extrahieren von Segmenten der Übereinstimmung verwendet werden. Darüber hinaus unterstützt es Wachen. Zum Beispiel:

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 

Nun, vielleicht wollten Sie fragen, was ist der Vorteil der Verwendung von Fall über mehrere Funktionsköpfe?

In diesem Fall ist es eine Frage des Stils/der Vorliebe. Es reduziert jedoch die Größe Ihrer Funktion. Ich bevorzuge den Ansatz mit mehreren Funktionsursachen, besonders wenn jeder Codeblock groß ist.

Verwandte Themen