Nic*_*ner 3 ocaml pattern-matching
是否可以对变量进行模式匹配而不是常量值:
# let x = 2 in
let y = 5 in
match 2 with
| x -> "foo"
| y -> "bar"
| _ -> "baz";;
let y = 5 in
Warning 26: unused variable y.
let x = 2 in
Warning 26: unused variable x.
| y -> "bar"
Warning 11: this match case is unused.
| _ -> "baz";;
Warning 11: this match case is unused.
- : string = "foo"
Run Code Online (Sandbox Code Playgroud)
显然,使用这种语法,x -> "foo"案例将占用一切.有没有办法使它等同于:
match 2 with
| 2 -> "foo"
| 5 -> "bar"
| _ -> "baz"
Run Code Online (Sandbox Code Playgroud)
匹配表达式的值是在运行时确定的?
一个when后卫是一个坏主意,在这里我的意见.初学者倾向于过度使用他们觉得方便的模式匹配语法,这导致他们的应用程序中的细微错误.对于一个会注意到"嘿,| y -> ..这不是我想要的"的人,其他十个人会犯错,不会直接注意到.
你应该劝阻这种易出错的模式.我对初学者的个人建议是永远不要使用when,并且只使用模式匹配来描述归纳数据类型的值(例如列表,树,选项等).整数上的模式匹配几乎总是一个错误.
我建议if ... then .. else if .. then .. else改用.
if z = x then "foo"
else if z = y then "bar"
else "baz"
Run Code Online (Sandbox Code Playgroud)
什么时候合法使用when?当其余案例确实受益于模式匹配(测试嵌套模式等),或者对匹配值的深度破坏产生的值执行测试时,可以理解.它通常可以通过合并两个分支并使用if..then..else本地来转换.
不便移除的一个示例如下(测试结合到解构):
match foo with
| (Baz x) when pred x -> ...
| _ -> ...
Run Code Online (Sandbox Code Playgroud)
你需要when警惕:
let x = 2 in
let y = 5 in
match 2 with
| z when z = x -> "foo"
| z when z = y -> "bar"
| _ -> "baz";;
Run Code Online (Sandbox Code Playgroud)
错误消息非常有启发性.当你使用:
let x = 2 in
...
match 2 with
| x -> "foo"
| ...
Run Code Online (Sandbox Code Playgroud)
新值会x影响x上一个let-bound中的值,从而影响第一条错误消息.此外,由于新x的比赛的一切,两个图案下方y,并_有明显的冗余.
请注意,匹配常量(match 2 with)不是一个好主意.