match 表达式 (F#)
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,然后将得到的值作为 match 表达式的值返回。
以上语法中显示的模式匹配函数是 lambda 表达式,此表达式在获得参数后会立即执行模式匹配。 以上语法中显示的模式匹配函数与以下函数等效。
fun arg ->
match arg with
|pattern1 [ when condition ] -> result-expression1
|pattern2 [ when condition ]-> result-expression2
| ...
有关 lambda 表达式的更多信息,请参见 Lambda 表达式:fun 关键字 (F#)。
整个模式集应涵盖输入变量的所有可能匹配项。 通常,可使用通配符模式 (_) 作为最后一个模式,以匹配任何前面未匹配的输入值。
下面的代码演示 match 表达式的一些用法。 有关可使用的所有可能模式的参考和示例,请参见模式匹配 (F#)。
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 子句来指定变量要匹配模式而必须满足的附加条件。 此类子句称为“先决条件”。 除非匹配与先决条件关联的模式,否则不会计算 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