Compartilhar via


Expressões match

A expressão match fornece controle de ramificação com base na comparação de uma expressão com um conjunto de padrões.

Sintaxe

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

Comentários

As expressões de padrões correspondentes permitem ramificação complexa com base na comparação de uma expressão de teste com um conjunto de padrões. Na expressão match, a expressão de teste é comparada a cada padrão individualmente e, quando uma correspondência é encontrada, a expressão de resultado correspondente é avaliada e o valor resultante é retornado como o valor da expressão de correspondência.

A função de padrões correspondentes mostrada na sintaxe anterior é uma expressão lambda na qual padrões correspondentes são executados imediatamente no argumento. A função de padrões correspondentes mostrada na sintaxe anterior é equivalente à seguinte.

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

Para saber mais sobre expressões lambda, confira Expressões lambda: a palavra-chave fun.

Todo o conjunto de padrões deve abranger todas as correspondências possíveis da variável de entrada. Com frequência, você usa o padrão curinga (_) como o último padrão para corresponder a qualquer valor de entrada sem correspondência anterior.

O código a seguir ilustra algumas das maneiras pelas quais a expressão match é usada. Para uma referência e exemplos de todos os padrões possíveis que podem ser usados, confira Padrões correspondentes.

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

Guardas em padrões

Você pode usar uma cláusula when para especificar uma condição adicional que a variável deve cumprir para corresponder a um padrão. Essa cláusula é conhecida como um guarda. A expressão que segue a palavra-chave when não é avaliada, a menos que haja uma correspondência com o padrão associado a esse guarda.

O exemplo a seguir ilustra o uso de um guarda para especificar um intervalo numérico para um padrão de variável. Observe que várias condições são combinadas usando operadores boolianos.

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

Como valores diferentes de literais não podem ser usados no padrão, você deverá usar uma cláusula when se precisar comparar alguma parte da entrada com um valor. Isso é mostrado no código a seguir:

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

Observe que, quando um padrão de união é coberto por um guarda, o guarda se aplica a todos os padrões, não apenas ao último. Por exemplo, dado o seguinte código, o guarda when a > 41 se aplica tanto a A a quanto 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

Confira também