下一个例子中的代码,
open System.Drawing
let testColor c =
match c with
| Color.Black -> 1
| Color.White -> 0
| _ -> failwith "unexpected color"
无法编译。错误是Error 1 The field, constructor or member 'Black' is not defined
。
如何针对以大写字母开头的.Net常量或枚举进行模式匹配?
对于它的价值,编译器是“Microsoft(R)F#2.0 Interactive build 4.0.30319.1”。
答案 0 :(得分:11)
根据Brian的回答,模式匹配与switch语句不同。它们测试和分解输入的结构而不是测试对象的相等性。但是如果在整个程序中经常使用分为黑色,白色和其他颜色的颜色,则可以选择活动模式。对于一次性“锅炉板”成本,它们允许您围绕要操纵的对象定义结构。例如,
open System.Drawing
let (|Black|White|Other|) (color:Color) =
if color = Color.Black then Black
elif color = Color.White then White
else Other
let testColor c =
match c with
| Black -> 1
| White -> 0
| Other -> failwith "unexpected color"
或者,如果你同样只处理黑白,但你总是希望Black评估为1而White要评估为0,那么你可以使用Partial Active Patterns:
let (|KnownColor|_|) (color:Color) =
if color = Color.Black then Some(1)
elif color = Color.White then Some(0)
else None
let testColor2 c =
match c with
| KnownColor i -> i
| _ -> failwith "unexpected color"
更一般地说,您甚至可以使用通用的部分活动模式模拟switch语句:
let (|Equals|_|) (lhs) (rhs) =
if lhs = rhs then Some(lhs) else None
let testColor3 c =
match c with
| Equals Color.Black _ -> 1
| Equals Color.White _ -> 0
| _ -> failwith "unexpected color"
let testString c =
match c with
| Equals "Hi" _ -> 1
| Equals "Bye" _ -> 0
| _ -> failwith "unexpected string"
答案 1 :(得分:5)
您无法对任意对象值进行模式匹配。使用if then else
或when
条件:
let testColor c =
match c with
| c when c = Color.Black -> 1
| c when c = Color.White -> 0
| _ -> failwith "unexpected color"