Python 的“with”语句对应的 OCaml 是什么?
with open('test.txt', 'r') as f:
# Do stuff with f
# At this point, f will always be closed, even in case of exceptions
即:OCaml 中的首选方式 是什么来安全地确保某个资源(打开的文件、数据库连接、HTTP 连接等)将始终在某个时间点被释放?在这里等待垃圾收集器是没有选择的,异常不应该阻止资源被释放。
当然,在 OCaml 中,您始终可以使用 try-finally 并“手动”关闭文件,就像在 Python 中一样。但是,这种代码很容易出错。这就是 Python 引入“with”语句的原因。使此类代码更易于阅读且不易出错的 OCaml 习语是什么?
请注意,这个问题与 Emulating try-with-finally in OCaml 的问题有很大不同。 ,因为这是更进一步:我不只是想在 OCaml 中模拟 try-finally! (顺便说一句,Lwt's [%finally ...] 做得很好。)我想更进一步,消除首先编写这些 finally 子句的需要——就像在 Python 中可以做的那样。
另请注意,这个问题不是关于实现细节,而是关于成语:在所有可能的设计和解决方案中,哪些在 OCaml 社区中获得了一定的吸引力并被普遍接受?
请您参考如下方法:
现在有Fun.protect这可能被认为(有效地)成语,因为它在标准库中。例如,
let get_contents file =
let ch = open_in file in
Fun.protect ~finally:(fun () -> close_in ch) begin fun () ->
let len = in_channel_length ch in
let bytes = Bytes.create len in
ignore (input ch bytes 0 len);
bytes
end
现在,甚至有 let-operators 正在慢慢找到更频繁使用的方法,例如https://github.com/ocaml/ocaml/pull/9887
所以你可以定义一个 let-op 来使用一个文件,比如:
let ( let& ) ch fn =
Fun.protect ~finally:(fun () -> close_in ch) begin fun () ->
fn ch
end
像这样使用它:
let get_contents file =
let& ch = open_in file in
let len = in_channel_length ch in
let bytes = Bytes.create len in
ignore (input ch bytes 0 len);
bytes
let& 运算符确保 in_channel 在当前作用域结束时关闭 (get_contents)。
