Выражения соответствия

matchВыражение обеспечивает управление ветвлением, основанное на сравнении выражения с набором шаблонов.

Синтаксис

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

Remarks

Выражения сопоставления шаблонов позволяют выполнять сложное ветвление на основе сравнения тестового выражения с набором шаблонов. В match выражении выражение теста сравнивается с каждым шаблоном, а при обнаружении совпадения вычисляется соответствующее результирующее выражение , а итоговое значение возвращается в качестве значения выражения соответствия.

Функция сопоставления шаблонов, показанная в предыдущем синтаксисе, представляет собой лямбда-выражение, в котором сопоставление шаблонов выполняется непосредственно над аргументом. Функция сопоставления шаблонов, показанная в предыдущем синтаксисе, эквивалентна следующей.

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

Дополнительные сведения о лямбда-выражениях см. в разделе Лямбда-выражения: fun ключевое слово.

Весь набор шаблонов должен охватывать все возможные совпадения входной переменной. Часто шаблон подстановочного знака () используется в _ качестве последнего шаблона для сопоставления с любыми ранее несовпадающими входными значениями.

В следующем коде показаны некоторые способы match использования выражения. Справочные сведения и примеры всех возможных шаблонов, которые можно использовать, см. в разделе сопоставление шаблонов.

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

Условия для шаблонов

Предложение можно использовать when для указания дополнительного условия, которым должна удовлетворять переменная для соответствия шаблону. Такое предложение называется условием. Выражение, следующее за when ключевым словом, не вычисляется, если в шаблон, связанный с этим условием, не установлено соответствие.

В следующем примере показано использование условия для указания числового диапазона для шаблона переменной. Обратите внимание, что несколько условий объединяются с помощью логических операторов.

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

Обратите внимание, что, поскольку значения, отличные от литералов, не могут использоваться в шаблоне, необходимо использовать when предложение, если необходимо сравнить некоторую часть входных данных со значением. Это продемонстрировано в приведенном ниже коде.

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

Обратите внимание, что если шаблон объединения охватывается условием, условие применяется ко всем шаблонам, а не только к последнему. Например, при наличии следующего кода условие when a > 12 применяется к 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

См. также