问题
The code in the next example,
open System.Drawing
let testColor c =
match c with
| Color.Black -> 1
| Color.White -> 0
| _ -> failwith "unexpected color"
doesn't compile. The error is Error 1 The field, constructor or member 'Black' is not defined
.
How do I pattern match against .Net constants or enums that start with capital letters?
For what it's worth, the compiler is "Microsoft (R) F# 2.0 Interactive build 4.0.30319.1".
回答1:
You can't pattern-match against arbitrary object values. Use an if then else
or when
conditions:
let testColor c =
match c with
| c when c = Color.Black -> 1
| c when c = Color.White -> 0
| _ -> failwith "unexpected color"
回答2:
Expanding upon Brian's answer, pattern-matches are a different beast than switch statements. They test and decompose the structure of an input rather than test object equality. But Active Patterns may be an option if the division of colors into Black, White and Other will be used often throughout your program. For a one-time "boiler-plate" cost, they let you define a structure around the object you are manipulating. For example,
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"
Or, if you are likewise dealing with only Black and White, but you always want Black to evaluate as 1 and White to evaluate as 0, then you can use 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"
More generally, you can even emulate a switch statement using a generic Partial Active Pattern:
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"
来源:https://stackoverflow.com/questions/4117667/f-pattern-matching-of-net-constants