Kifejezések egyeztetése

A match kifejezés elágaztatási vezérlőt biztosít, amely egy kifejezés mintákkal való összehasonlításán alapul.

Szemantika

// 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
| ...

Megjegyzések

A mintaegyező kifejezések lehetővé teszik az összetett elágazást a tesztkifejezések és a minták halmazának összehasonlítása alapján. A kifejezésben a matchtesztkifejezés az egyes mintákkal lesz összehasonlítva, és ha talál egyezést, a rendszer kiértékeli a megfelelő eredménykifejezést , és az eredményül kapott értéket adja vissza az egyezés kifejezés értékeként.

Az előző szintaxisban látható mintaegyeztetési függvény egy lambda kifejezés, amelyben a mintaegyeztetés közvetlenül az argumentumon történik. Az előző szintaxisban látható mintamegfeleltetési függvény az alábbiaknak felel meg.

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

További információ a lambda kifejezésekről: Lambda Expressions: The fun Keyword.

A teljes mintakészletnek a bemeneti változó összes lehetséges egyezésére ki kell terjednie. Gyakran a helyettesítő minta (_) az utolsó minta, amely megfelel a korábban nem egyező bemeneti értékeknek.

Az alábbi kód bemutatja a kifejezés felhasználási módjait match . A használható mintákra vonatkozó hivatkozásért és példákért lásd: Mintaegyeztetés.

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

Minták őrzése

Használhat egy when feltételt, hogy megadjon egy további feltételt, amelynek a változónak meg kell felelnie, hogy megfeleljen egy mintának. Az ilyen záradékot őrnek nevezzük. A when kulcsszót követő kifejezés csak akkor lesz kiértékelve, ha az őrsorra kapcsolódó mintával történik egyezés.

Az alábbi példa azt szemlélteti, hogy egy védő használatával numerikus tartományt adhat meg egy változómintához. Vegye figyelembe, hogy a rendszer több feltételt kombinál logikai operátorokkal.

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

Vegye figyelembe, hogy mivel a mintában a literáltól eltérő értékek nem használhatók, záradékot when kell használnia, ha a bemenet egy részét össze kell hasonlítania egy értékkel. Ez a következő kódban jelenik meg:

// 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

Vegye figyelembe, hogy ha egy egyesítési mintát őr véd, az őr az összes mintára érvényes, nem csak az utolsóra. Az alábbi kód alapján például a védő when a > 41 mind a A a-re, mind a B a-re vonatkozik.

type Union =
    | A of int
    | B of int

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

foo() // returns 1

Lásd még