exception - 使用异常中断对文件行的迭代

标签 exception ocaml

有一些文本文件需要逐行操作。我写了一个 withFile功能如下:

let withFile fn handle =
    let rec iter_lines fh =
    try
        handle (input_line fh);
        iter_lines fh
    with _ -> close_in fh in
    iter_lines (open_in fn);;

所以我可以将每个文件操作为:
withFile "file1.txt" (fun line -> (*...*))
withFile "file2.txt" (fun line -> (*...*))
...

但是当我不想处理所有行时,我不确定如何优雅地退出。例如:
withFile "file3.txt" (fun line ->
   (*when the line meets some condition, i will exit without handling other lines*)
);

任何建议表示赞赏!

最佳答案

您的职能 iter_lines不是尾递归的,这意味着如果您以这种方式处理非常大的文件,您可能会耗尽堆栈空间。它不是尾递归的原因是它必须建立和拆除 try ... with异常捕获机制。

除此之外,这对我来说真的很好。这种高阶函数就是 OCaml(和 FP)的全部内容。

使其尾递归的一种方法是将异常处理移出包含函数。我还会更具体地说明您要处理的异常。所以你得到这个:

let withFile fn handle =
    let rec iter_lines fh =
        handle (input_line fh);
        iter_lines fh
    in
    let fh = open_in fn in
    try iter_lines fh
    with End_of_file -> close_in fh

如果您希望能够提前退出,一种简单的方法是让您的句柄函数返回一个 bool 值,告诉您是否继续处理行。你最终会得到这样的结果:
let withFile fn handle =
    let rec iter_lines fh =
        if handle (input_line fh) then
            iter_lines fh
    in
    let fh = open_in fn in
    try iter_lines fh
    with End_of_file -> close_in fh

如果您希望能够使用异常提前退出,您需要捕获 withFile 中的所有异常。 , 关闭文件,然后重新引发除 End_of_file 之外的任何异常.这为您提供了如下所示的代码:
let withFile fn handle =
    let rec iter_lines fh =
        handle (input_line fh);
        iter_lines fh
    in
    let fh = open_in fn in
    try iter_lines fh
    with e ->
        (close_in fh; if e <> End_of_file then raise e)

关于exception - 使用异常中断对文件行的迭代,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8101735/

相关文章:

list - OCaml:检查成员记录列表

安卓截击 : how to handle the error response

c++ - Socket库是否在C++中使用异常?

java - Java什么时候出现ERROR?

refactoring - 如何简化此 ocaml 模式匹配代码?

ocaml - 带反引号 "` "和不带反引号有什么区别?

c# - 使用 InvariantCulture 或 CurrentCulture 格式化异常消息?

c# - LIST<> AddRange 抛出 ArgumentException

ocaml - OCaml中的仿函数设计

json - 使用可用的库 (Yojson) 启动交互式 OCaml session