比對運算式
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
運算式中,test-expression 會依次與每個模式進行比較,當找到相符項時,對應的 result-expression 會被評估,並將產生的值當做比對運算式的值傳回。
上述語法中所示的模式比對函式是一個 Lambda 運算式,在其中會立即對引數執行模式比對。 上述語法中所示的模式比對函式相當於下列內容。
fun arg ->
match arg with
| pattern1 [ when condition ] -> result-expression1
| pattern2 [ when condition ] -> result-expression2
| ...
如需 Lambda 運算式的詳細資訊,請參閱 Lambda 運算式: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
子句來指定變數必須滿足以符合模式的額外條件。 這類子句稱為成立條件子句 (guard)。 除非對與該成立條件相關聯的模式進行比對,否則不會評估 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
請注意,因為常值 (literal) 以外的值不能用於模式中,如果您必須將輸入的某個部分與某個值進行比較時,則必須使用 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 42
match test with
| A a
| B a when a > 41 -> a // the guard applies to both patterns
| _ -> 1
foo() // returns 42