以下代码......
type 'a osResult =
Success of 'a
| Error of string
let errorCatcher f =
try
let result = f () in
Success result
with Unix.Unix_error (code, fun_name, arg) ->
Error(String.concat ":" [(Unix.error_message code); fun_name; arg])
let my_getcwd () =
errorCatcher (fun () -> Unix.getcwd ())
let _ =
print_endline "The Start";
let result = my_getcwd () |> function
| Success folder -> Printf.sprintf "getcwd:\n\t%s\n" folder
| Error errMessage -> Printf.sprintf "getcwd (error):\n\t%s\n" errMessage
in
print_string result ;
print_endline "The End."
;;
...编译好:
$ corebuild -tag debug test1.native
......运行良好:
$ ./test1.native
The Start
getcwd:
/home/ttsiod/work/byePythonHelloOCaml
The End.
但如果我将主体更改为:
let _ =
print_endline "The Start";
my_getcwd () |> function
| Success folder -> Printf.printf "getcwd:\n\t%s\n" folder
| Error errMessage -> Printf.printf "getcwd (error):\n\t%s\n" errMessage
;
print_endline "The End."
;;
...然后显然最后一个印刷声明("结束")丢失或者其他东西......
$ ./test2.native
The Start
getcwd:
/home/ttsiod/work/byePythonHelloOCaml
最初,我认为这是stdout缓冲未被刷新的情况。
但print_endline
的文档清楚地声称它冲刷了stdout,所以我不知所措 - 并且添加" flush"没有帮助,或者:
let _ =
print_endline "The Start";
my_getcwd () |> function
| Success folder -> Printf.printf "getcwd:\n\t%s\n" folder
| Error errMessage -> Printf.printf "getcwd (error):\n\t%s\n" errMessage
;
print_endline "The End." ;
flush stdout
;;
帮助?
答案 0 :(得分:3)
print_endline
被视为Error
案例的一部分。从缩进来看,这显然不是你的意思,但不幸的是,OCaml编译器并没有对此发出警告。
您可以使用begin
和end
(或只是括号)来使其有效:
let () =
print_endline "The Start";
my_getcwd () |> begin function
| Success folder -> Printf.printf "getcwd:\n\t%s\n" folder
| Error errMessage -> Printf.printf "getcwd (error):\n\t%s\n" errMessage
end;
print_endline "The End." ;
flush stdout
或者,不使用;
,
let () =
let () = print_endline "The Start" in
let () = match my_getcwd () with
| Success folder -> Printf.printf "getcwd:\n\t%s\n" folder
| Error errMessage -> Printf.printf "getcwd (error):\n\t%s\n" errMessage
in
let () = print_endline "The End." in
flush stdout