Share via


Matcha uttryck

Uttrycket match ger förgreningskontroll som baseras på jämförelsen av ett uttryck med en uppsättning mönster.

Syntax

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

Kommentarer

Mönstermatchningsuttrycken möjliggör komplex förgrening baserat på jämförelsen av ett testuttryck med en uppsättning mönster. match I uttrycket jämförs testuttrycket med varje mönster i tur och ordning, och när en matchning hittas utvärderas motsvarande resultatuttryck och det resulterande värdet returneras som värdet för matchningsuttrycket.

Den mönstermatchningsfunktion som visas i föregående syntax är ett lambda-uttryck där mönstermatchning utförs omedelbart på argumentet. Den mönstermatchningsfunktion som visas i föregående syntax motsvarar följande.

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

Mer information om lambda-uttryck finns i Lambda-uttryck: Nyckelordetfun.

Hela uppsättningen mönster bör omfatta alla möjliga matchningar för indatavariabeln. Ofta använder du jokertecknet (_) som det sista mönstret för att matcha tidigare omatchade indatavärden.

Följande kod illustrerar några av de sätt på match vilka uttrycket används. En referens och exempel på alla möjliga mönster som kan användas finns i Mönstermatchning.

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

Skydd på mönster

Du kan använda en when sats för att ange ytterligare ett villkor som variabeln måste uppfylla för att matcha ett mönster. En sådan klausul kallas för en vakt. Uttrycket som följer nyckelordet when utvärderas inte om inte en matchning görs med det mönster som är associerat med det skyddet.

I följande exempel visas användningen av ett skydd för att ange ett numeriskt intervall för ett variabelmönster. Observera att flera villkor kombineras med hjälp av booleska operatorer.

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

Observera att eftersom andra värden än literaler inte kan användas i mönstret måste du använda en when sats om du måste jämföra en del av indata med ett värde. Detta visas i följande kod:

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

Observera att när ett unionsmönster täcks av en vakt gäller skyddet för alla mönster, inte bara den sista. Med hjälp av följande kod gäller till exempel skyddet when a > 41 för både A a och 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

Se även