共用方式為


匹配表達式

表達式 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
| ...

備註

模式比對表達式允許根據測試表達式與一組模式的比較,進行複雜的分支。 在此表達式中,matchtest-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

請注意,由於常值以外的值不能用於模式中,因此您必須使用 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 aB 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

另請參閱