匹配表达式

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 表达式中, 测试表达式 依次与每个模式进行比较,当找到匹配项时,将计算相应的 结果表达式 ,并将结果值作为匹配表达式的值返回。

上一语法中显示的模式匹配函数是 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 表达式。

下面的示例演示如何使用 guard 为变量模式指定数值范围。 请注意,使用布尔运算符组合多个条件。

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

另请参阅