Shoda výrazů
Výraz match
poskytuje ovládací prvek větvení, který je založen na porovnání výrazu se sadou vzorů.
Syntaxe
// 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
| ...
Poznámky
Výrazy porovnávání vzorů umožňují komplexní větvení na základě porovnání testovacího výrazu se sadou vzorů. Ve výrazu match
se test-výraz porovná s každým vzorem a když se najde shoda, vyhodnotí se odpovídající výsledek výrazu a výsledná hodnota se vrátí jako hodnota výrazu shody.
Funkce porovnávání vzorů zobrazená v předchozí syntaxi je výraz lambda, ve kterém se porovnávání vzorů provádí okamžitě u argumentu. Funkce porovnávání vzorů zobrazená v předchozí syntaxi je ekvivalentní následujícímu.
fun arg ->
match arg with
| pattern1 [ when condition ] -> result-expression1
| pattern2 [ when condition ] -> result-expression2
| ...
Další informace o výrazech lambda najdete v tématu Výrazy lambda: Klíčové fun
slovo.
Celá sadavzorch Vzor se zástupnými znaménami (_
) často používáte jako poslední vzor, abyste se shodovali s předchozími chybějícími vstupními hodnotami.
Následující kód znázorňuje některé způsoby použití výrazu match
. Referenční informace a příklady všech možných vzorů, které lze použít, najdete v tématu Porovnávání vzorů.
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
Ochrana vzorů
Klauzuli můžete použít when
k určení další podmínky, kterou proměnná musí splňovat, aby odpovídala vzoru. Taková klauzule se označuje jako stráž. Výraz následující za when
klíčovým slovem se nevyhodnocuje, pokud se neshoda neprovedou se vzorem přidruženým k tomuto strážci.
Následující příklad znázorňuje použití stráže k určení číselného rozsahu pro proměnný vzor. Všimněte si, že pomocí logických operátorů se zkombinuje více podmínek.
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
Všimněte si, že vzhledem k tomu, že hodnoty jiné než literály nelze ve vzoru použít, je nutné použít when
klauzuli, pokud potřebujete porovnat část vstupu s hodnotou. Toto je znázorněno v následujícím kódu:
// 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
Všimněte si, že když je vzor sjednocení pokrytý stráží, ochrana se vztahuje na všechny vzory, nejen na poslední vzor. Například vzhledem k následujícímu kódu se ochrana when a > 41
vztahuje na obě A a
a 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