所以,我对OCaml完全不熟悉,并且在实现我的第一个功能方面进展缓慢。我无法理解的一件事是何时使用模式匹配能力,如
let foo =
[] -> true
| _ -> false;;
使用if else结构,如
let foo a =
if a = [] then true else false;;
我什么时候应该使用它们?
答案 0 :(得分:17)
我认为这个问题没有明确的答案。首先,模式匹配的明显例子是你需要破坏时,例如:
let rec sum = function
| [] -> 0
| head :: tail -> head + sum tail;;
另一个明显的例子是当你定义一个递归函数时,模式匹配使边缘条件更清晰,例如:
let rec factorial = function
| 0 -> 1
| n -> n * factorial(n - 1);;
而不是:
let rec factorial = function n ->
if n = 0 then
1
else
n * factorial(n-1);;
这可能不是一个很好的例子,只需用你的想象力来找出更复杂的边缘条件! ; - )
对于常规(比如C语言)语言,我可以说你应该使用模式匹配而不是switch
/ case
和if
来代替三元运算符。对于其他一切,它是一种灰色区域,但在ML系列语言中通常首选模式匹配。
答案 1 :(得分:2)
据我所知,显着区别在于匹配语句中守卫的表达式是pattern,这意味着你可以做一些事情,让你分开形状(破坏)匹配的表达式,正如尼古拉斯在答案中所表明的那样。另一个含义是这样的代码:
let s = 1 in
let x = 2 in
match s with
x -> Printf.printf "x does not equal s!!\n" x
| _ -> Printf.printf "x = %d\n" x;
不会做你期望的。这是因为match语句中的x
没有引用它上面的let语句中的x
,但它是模式的名称。在这种情况下,您需要使用if
语句。
答案 2 :(得分:0)
模式匹配允许解构复合数据类型,并且通常能够匹配给定数据结构中的模式,而不是使用if ... then结构之类的条件。模式匹配也可以用于使用| x when(r == n)类型构造的布尔相等情况。我还应该添加模式匹配比if ... then ..结构更高效,所以请大量使用它!
答案 3 :(得分:0)
对我来说,.. then..else等效于将..与|匹配。 true-> .. |假 - > ..,但有,如果你正面临着嵌套模式匹配的情况下语法糖,使用的if..else在隔行扫描方式可以帮助您避免使用开始...结束区分不同层次的模式
match .. with
| true ->
if .. then
match .. with
| true -> ..
| false -> ..
else
...
| false -> ...
比
更紧凑match .. with
| true ->
begin
match .. with
| true ->
begin
match .. with
| true -> ..
| false -> ..
end
| false ->
...
end
| false -> ...