OCaml 中与 Python 的“with”语句相对应的是什么?
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 习惯用法是什么?
请注意,这个问题与问题有很大不同在 OCaml 中模拟 try-with-finally https://stackoverflow.com/questions/11276985/emulating-try-with-finally-in-ocaml,因为这是更进一步:我不只是想在 OCaml 中模拟 try-finally! (在哪里Lwt's [%finally ...] https://ocsigen.org/lwt/3.2.1/api/Ppx_lwt顺便说一句,做得很好。)我想更进一步,消除一开始就编写这些finally 子句的需要——就像在Python 中所做的那样。
另请注意,这个问题是不涉及实施细节, but 关于成语:所有可能的设计和解决方案中,哪些在 OCaml 社区中获得了一些关注并被普遍接受?
现在有乐趣保护 https://ocaml.org/api/Fun.html#VALprotect这可以被认为(有效地)是习惯用法,因为它位于标准库中。例如。,
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 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
The let&
操作员确保in_channel
在当前范围结束时关闭(get_contents
).
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)