为什么第二个模式匹配返回“ 1和2”并在通配符_上警告我“此规则将永远不会匹配”?
let a = [3;4]
match a with
|[1;2] -> "1 and 2"
|_ -> "Other"
|> printfn "%A"
let lst = [1;2]
match a with
|lst -> "1 and 2"
|_ -> "Other"
|> printfn "%A"
在我看来,这首先是事实。怎么这样?
答案 0 :(得分:3)
小写的标识符与所有内容匹配,并将标识符绑定到值。
如果要将lst
与a
进行比较,则需要使用when
,它是有条件的保护措施:
let a = [3;4]
match a with
|[1;2] -> "1 and 2"
|_ -> "Other"
|> printfn "%A"
let lst = [1;2]
match a with
| b when b = lst -> "1 and 2"
|_ -> "Other"
|> printfn "%A"
,但在这种情况下,简单的if then else
就可以了。
答案 1 :(得分:1)
在第二个模式匹配中,您有两个具有相同名称的不同lst
变量。在这里,
let lst = [1;2]
match a with
| lst -> "1 and 2"
| _ -> "Other"
在第一种匹配情况下,您没有引用上面的lst
变量,则创建了一个新变量。您可以通过尝试对其进行重构-重命名(在Visual Studio中为F2)进行检查。正如AMieres解释的那样,案例很重要。
通常,在区分大小写的情况下引用变量是可行的,但并非易事。 考虑以下代码:
let helloWorld = "hello world"
let isHelloWorld s =
match s with
| helloWorld -> true
| _ -> false
在这里您将得到与上述相同的警告。一种可行的方法是用[<Literal>]
属性标记常量,并同时使其变为大写:
[<Literal>]
let HelloWorld = "hello world"
let isHelloWorld s =
match s with
| HelloWorld -> true
| _ -> false
这将按预期工作。但是,您只能将[<Literal>]
属性应用于certain types,并且列表不在其中。对于这些,您必须在匹配情况下利用when
条件。