Dopasowywanie wyrażeń

Wyrażenie match zapewnia kontrolkę rozgałęziania opartą na porównywaniu wyrażenia z zestawem wzorców.

Składnia

// Match expression.
match test-expression with
| pattern1 [ when condition ] -> result-expression1
| pattern2 [ when condition ] -> result-expression2
| ...

// Pattern matching function.
function
| pattern1 [ when condition ] -> result-expression1
| pattern2 [ when condition ] -> result-expression2
| ...

Uwagi

Wyrażenia dopasowania wzorca umożliwiają złożone rozgałęzianie na podstawie porównania wyrażenia testowego z zestawem wzorców. W wyrażeniu matchwyrażenie-test jest porównywane z każdym wzorcem z kolei, a gdy zostanie znalezione dopasowanie, odpowiednie wyrażenie-wynik jest obliczane, a wynikowa wartość jest zwracana jako wartość wyrażenia dopasowania.

Funkcja dopasowywania wzorca pokazana w poprzedniej składni jest wyrażeniem lambda, w którym dopasowanie wzorca jest wykonywane natychmiast na argumencie. Funkcja dopasowywania wzorca pokazana w poprzedniej składni jest równoważna poniższemu.

fun arg ->
    match arg with
    | pattern1 [ when condition ] -> result-expression1
    | pattern2 [ when condition ] -> result-expression2
    | ...

Aby uzyskać więcej informacji na temat wyrażeń lambda, zobacz Wyrażenia lambda: fun Słowo kluczowe.

Cały zestaw wzorców powinien obejmować wszystkie możliwe dopasowania zmiennej wejściowej. Często używasz wzorca wieloznacznego (_) jako ostatniego wzorca, aby dopasować wszystkie wcześniej niedopasowane wartości wejściowe.

Poniższy kod ilustruje niektóre sposoby użycia match wyrażenia. Aby zapoznać się z dokumentacją i przykładami wszystkich możliwych wzorców, które mogą być używane, zobacz Dopasowywanie wzorców.

let list1 = [ 1; 5; 100; 450; 788 ]

// Pattern matching by using the cons pattern and a list
// pattern that tests for an empty list.
let rec printList listx =
    match listx with
    | head :: tail -> printf "%d " head; printList tail
    | [] -> printfn ""

printList list1

// Pattern matching with multiple alternatives on the same line.
let filter123 x =
    match x with
    | 1 | 2 | 3 -> printfn "Found 1, 2, or 3!"
    | a -> printfn "%d" a

// The same function written with the pattern matching
// function syntax.
let filterNumbers =
    function | 1 | 2 | 3 -> printfn "Found 1, 2, or 3!"
             | a -> printfn "%d" a

Strażniki na wzorcach

Można użyć klauzuli when , aby określić dodatkowy warunek, który zmienna musi spełnić, aby dopasować wzorzec. Taka klauzula jest nazywana strażnikiem. Wyrażenie następujące po słowie when kluczowym nie jest oceniane, chyba że zostanie wykonane dopasowanie do wzorca skojarzonego z tą strażą.

W poniższym przykładzie pokazano użycie funkcji ochrony w celu określenia zakresu liczbowego dla wzorca zmiennej. Należy pamiętać, że wiele warunków jest połączonych przy użyciu operatorów logicznych.

let rangeTest testValue mid size =
    match testValue with
    | var1 when var1 >= mid - size/2 && var1 <= mid + size/2 -> printfn "The test value is in range."
    | _ -> printfn "The test value is out of range."

rangeTest 10 20 5
rangeTest 10 20 10
rangeTest 10 20 40

Należy pamiętać, że ponieważ wartości inne niż literały nie mogą być używane we wzorcu, należy użyć when klauzuli , jeśli trzeba porównać część danych wejściowych z wartością. Jest to pokazane w następującym kodzie:

// This example uses patterns that have when guards.
let detectValue point target =
    match point with
    | (a, b) when a = target && b = target -> printfn "Both values match target %d." target
    | (a, b) when a = target -> printfn "First value matched target in (%d, %d)" target b
    | (a, b) when b = target -> printfn "Second value matched target in (%d, %d)" a target
    | _ -> printfn "Neither value matches target."
detectValue (0, 0) 0
detectValue (1, 0) 0
detectValue (0, 10) 0
detectValue (10, 15) 0

Należy pamiętać, że gdy wzorzec unii jest objęty osłoną, ochrona ma zastosowanie do wszystkich wzorców, a nie tylko do ostatnich. Na przykład, biorąc pod uwagę następujący kod, ochrona when a > 41 ma zastosowanie zarówno do , jak A a i B a:

type Union =
    | A of int
    | B of int

let foo() =
    let test = A 42
    match test with
    | A a
    | B a when a > 41 -> a // the guard applies to both patterns
    | _ -> 1

foo() // returns 42

Zobacz też