2

我在使用 OCaml 开发应用程序中关注这个draw_string_in_box示例

给出的示例代码如下:

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;;

如果我删除“匹配”部分周围的括号,代码将不起作用(什么都不会打印)。知道为什么吗?

更一般地说,我什么时候应该在这样的代码位周围加上括号?

谢谢。

4

2 回答 2

5

一种看待它的方法是,在语句的箭头之后,->match可以有一系列表达式(用 分隔;)。如果没有括号,以下表达式看起来像是match.

您还可以在 之后有一系列表达式(由 分隔;let。使用括号,以下表达式看起来像是 的一部分let,这就是您想要的。

我个人避免使用;. 我就是这样处理这个问题的!否则,您必须确定表达式序列与采用序列的最里面的构造一起使用。

于 2012-09-19T16:49:42.977 回答
3

正如 Jeffrey 所解释的,如果您删除括号,则这些Graphics.set_color col; Graphics.draw_string str陈述被理解为| Left ->案例的一部分。

这个答案更多地是关于何时在此类代码摘录中使用括号。在大多数情况下,模式匹配是函数的最后一个表达式,例如:

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);

这里第一个括号是强制性的,第二个是可选的,通常不写。

于 2012-09-19T21:08:39.240 回答