Expressões de correspondência
A match
expressão fornece controle de ramificação que se baseia 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
| ...
Observações
As expressões de correspondência de padrões permitem ramificações complexas com base na comparação de uma expressão de teste com um conjunto de padrões. Na expressão, a match
expressão-teste é comparada com cada padrão por vez, e quando uma correspondência é encontrada, a expressão-resultado correspondente é avaliada e o valor resultante é retornado como o valor da expressão de correspondência.
A função de correspondência de padrão mostrada na sintaxe anterior é uma expressão lambda na qual a correspondência de padrão é executada imediatamente no argumento. A função de correspondência de padrões mostrada na sintaxe anterior é equivalente à seguinte.
fun arg ->
match arg with
| pattern1 [ when condition ] -> result-expression1
| pattern2 [ when condition ] -> result-expression2
| ...
Para obter mais informações sobre expressões lambda, consulte Expressões lambda: a fun
palavra-chave.
Todo o conjunto de padrões deve abranger todas as correspondências possíveis da variável de entrada. Freqüentemente, você usa o padrão curinga (_
) como o último padrão para corresponder a quaisquer valores de entrada incompatíveis anteriormente.
O código a seguir ilustra algumas das maneiras pelas quais a match
expressão é usada. Para obter uma referência e exemplos de todos os padrões possíveis que podem ser usados, consulte Correspondência de padrões.
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 when
cláusula para especificar uma condição adicional que a variável deve satisfazer para corresponder a um padrão. Tal cláusula é referida como guarda. A expressão que segue a palavra-chave não é avaliada, when
a menos que seja feita uma correspondência com o padrão associado a esse protetor.
O exemplo a seguir ilustra o uso de um protetor para especificar um intervalo numérico para um padrão variável. Observe que várias condições são combinadas usando operadores booleanos.
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
Observe que, como valores diferentes de literais não podem ser usados no padrão, você deve usar uma when
cláusula se tiver que 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, a guarda when a > 41
aplica-se a ambos e 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