给出的示例代码如下:
let draw_string_in_box pos str bcf col =
let (w, h) = Graphics.text_size str in
let ty = bcf.y + (bcf.h-h)/2 in
( match pos with
Center -> Graphics.moveto (bcf.x + (bcf.w-w)/2) ty
| Right -> let tx = bcf.x + bcf.w - w - bcf.bw - 1 in
Graphics.moveto tx ty
| Left -> let tx = bcf.x + bcf.bw + 1 in Graphics.moveto tx ty );
Graphics.set_color col;
Graphics.draw_string str;;
如果我删除“匹配”部分周围的括号,则代码将无效(无法打印任何内容)。知道为什么吗?
更一般地说,我应该何时将括号括在像这样的代码位?
感谢。
答案 0 :(得分:5)
查看它的一种方法是在->
语句的箭头match
之后,您可以有一系列表达式(由;
分隔)。如果没有括号,以下表达式看起来就像是match
的最后一个案例的一部分。
在;
之后,您还可以拥有一系列表达式(由let
分隔)。使用括号,以下表达式看起来像是let
的一部分,这就是您想要的。
我个人避免使用;
。这就是我如何处理这个问题!否则,您必须确定表达序列与采用序列的最内层构造一致。
答案 1 :(得分:3)
正如Jeffrey所解释的,如果删除括号,则Graphics.set_color col; Graphics.draw_string str
语句被理解为| Left ->
个案的一部分。
这个答案更多的是关于何时在这些代码摘录中使用括号。 在大多数情况下,模式匹配是函数的 last 表达式,例如:
let f x y =
foo x;
match y with
| Bar -> Printf.printf "Found y=Bar!\n%!"; 42
| Baz -> Printf.printf "Found y=Baz!\n%!"; 43
在这种情况下,您不需要括号。通常,它也是第一个,因此也是函数的唯一表达式:
let hd list = match list with
| a :: _ -> a
| [] -> invalid_arg "hd"
但是当你想在匹配后做事时,你需要告诉OCaml匹配结束的地方。这是您使用括号的地方:
let f x y =
foo x;
(match y with
| Bar -> 42
| Baz -> 43);
(* do something, both when y is Bar and when it is Baz: *)
qux x y;
同样适用于try ... with
陈述:
let find_a_b a b list =
(try print_int List.assoc a list
with Not_found -> Printf.printf "Could not find a=%s.\n%!" a);
(* Now do something whether or not we found a: *)
(try print_int List.assoc b list
with Not_found -> Printf.printf "Could not find b=%s.\n%!" b);
这里第一个括号是强制性的,秒是可选的,通常不写。