与 Python 的“with"语句(资源的自动释放)对应的 OCaml 是什么? [英] What is the OCaml counterpart to Python's "with"-statement (automatic release of resources)

查看:72
本文介绍了与 Python 的“with"语句(资源的自动释放)对应的 OCaml 是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

与 Python 的with"语句对应的 OCaml 是什么?

What is the OCaml counterpart to Python's "with"-statement?

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连接等)总是在某个时间点被释放?等待垃圾收集器在这里是没有选择的,异常不应该阻止资源被释放.

That is: What is the preferred way in OCaml to safely ensure that a certain resource (open file, database connection, HTTP connection, etc.) will always be freed at a certain point in time? Waiting for the garbage collector is no option here, and exceptions should never prevent resources from being freed.

当然,在 OCaml 中,您始终可以使用 try-finally 并手动"关闭文件,就像在 Python 中一样.但是,这种代码容易​​出错.这就是 Python 引入with"语句的原因.使这种代码更易于阅读且不易出错的 OCaml 习语是什么?

Of course, in OCaml you can always use try-finally and close the file "by hand", as you can do in Python. However, that kind of code is prone to errors. This is why Python introduced the "with"-statement. What's the OCaml idiom to make this kind of code easier to read and less prone to errors?

注意这个问题与Emulating try-with-finally inOCaml,因为这是更进一步:我不只是想在 OCaml 中模拟 try-finally!(其中 Lwt 的 [%finally ...] 顺便说一句,做得很好.)我想更进一步,首先消除编写那些 finally 子句的需要 - 就像在 Python 中可以做到的那样.

Note that this question is very different from the question Emulating try-with-finally in OCaml, as this is one step further: I don't just want to emulate try-finally in OCaml! (where Lwt's [%finally ...] does a fine job, by the way.) I want to get one step further, eliminating the need to write those finally-clauses in the first place - as one can do in Python.

另请注意,这个问题不是关于实现细节,而是关于习惯用法:在所有可能的设计和解决方案中,哪些在 OCaml 社区中获得了一些牵引力并被普遍接受?

Also note that this question is not about implementation details, but about idioms: Which of all possible designs and solutions gained some traction in the OCaml community and is generally accepted?

推荐答案

现在有 乐趣.保护 这可能被认为(有效地)成语,因为它在标准库中.例如,

There is now Fun.protect which may be considered (effectively) the idiom, since it's in the standard library. E.g.,

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

如今,甚至还有让运营商慢慢找到更频繁使用的方​​式,例如https://github.com/ocaml/ocaml/pull/9887

Nowadays, there are even let-operators which are slowly finding their way into more frequent use, e.g. https://github.com/ocaml/ocaml/pull/9887

所以你可以定义一个 let-op 来使用一个文件,比如:

So you could define a let-op to use a file, like:

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) 结束时关闭.

The let& operator makes sure the in_channel is closed at the end of the current scope (get_contents).

这篇关于与 Python 的“with"语句(资源的自动释放)对应的 OCaml 是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆