OCaml 对应于 Python 的“with”语句(自动释放资源)是什么?

2024-03-16

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(使用前将#替换为@)

OCaml 对应于 Python 的“with”语句(自动释放资源)是什么? 的相关文章

随机推荐