Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Выражение 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
| ...
Замечания
Выражения сопоставления шаблонов позволяют выполнять сложные ветвления на основе сравнения тестового выражения с набором шаблонов.
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 > 41
применяется к обоим A a
и B a
:
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