Condividi tramite


Espressioni di confronto

L'espressione match fornisce un controllo di diramazione basato sul confronto di un'espressione con un set di modelli.

Sintassi

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

Osservazioni:

Le espressioni di confronto consentono una ramificazione complessa basata sul confronto di un'espressione di test con un insieme di modelli. Nell'espressione, l'espressione matchtest viene confrontata con ogni criterio a sua volta e quando viene trovata una corrispondenza, viene valutata l'espressione di risultato corrispondente e il valore risultante viene restituito come valore dell'espressione di corrispondenza.

La funzione di corrispondenza dei modelli mostrata nella sintassi precedente è un'espressione lambda in cui la corrispondenza dei modelli viene eseguita immediatamente sull'argomento. La funzione di corrispondenza dei modelli illustrata nella sintassi precedente equivale alla seguente.

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

Per altre informazioni sulle espressioni lambda, vedere Espressioni lambda: parola fun chiave.

L'intero set di modelli deve coprire tutte le possibili corrispondenze della variabile di input. Spesso si utilizza il modello con caratteri jolly (_) come schema finale per abbinare qualsiasi valore di input precedentemente non corrispondente.

Il codice seguente illustra alcuni dei modi in cui viene usata l'espressione match . Per informazioni di riferimento ed esempi di tutti i possibili modelli che è possibile usare, vedere Pattern Matching.

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

Protezioni sui modelli

È possibile usare una clausola per specificare una when condizione aggiuntiva che la variabile deve soddisfare per corrispondere a un criterio. Tale clausola viene definita condizione di guardia. L'espressione che segue la parola chiave when non viene valutata a meno che non venga fatta una corrispondenza con il modello associato a tale guardia.

Nell'esempio seguente viene usata una guardia per specificare un intervallo numerico in uno schema di variabile. Si noti che più condizioni vengono combinate usando operatori booleani.

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

Si noti che poiché non è possibile usare valori diversi dai valori letterali nel modello, è necessario usare una when clausola se è necessario confrontare parte dell'input con un valore. Questo è illustrato nel codice seguente:

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

Si noti che quando un modello di unione è coperto da una protezione, la protezione si applica a tutti i modelli, non solo all'ultimo. Ad esempio, dato il codice seguente, la protezione when a > 41 si applica sia a A a che 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

Vedere anche