流处理与增量 I/O 全解析
1. 命令式 I/O 的问题
在处理与外部世界交互的程序时,命令式 I/O 存在诸多问题。以检查文件行数是否超过 40000 为例,使用命令式代码在 IO 单子中实现如下:
def linesGt40k(filename: String): IO[Boolean] = IO:
val src = io.Source.fromFile(filename)
try
var count = 0
val lines: Iterator[String] = src.getLines()
while count <= 40000 && lines.hasNext do
lines.next
count += 1
count > 40000
finally src.close
这段代码有一定优点,比如具有增量性,不会一次性将整个文件加载到内存,且能提前终止计算。但也存在明显缺点:
- 资源泄漏风险 :需要手动关闭文件,若忘记或在异常发生时未正确关闭,会导致文件句柄一直打开,造成资源泄漏。
- 缺乏组合性 :代码将高层算法与迭代和文件访问等底层细节纠缠在一起,难以扩展和维护。例如,若要检查非空行数是否超过 40000 或查找特定字符串,代码会变得复杂且难以编写。
我们可以尝试使用惰性 I/O,返回一个 IO[LazyList[String]] : </
订阅专栏 解锁全文

被折叠的 条评论
为什么被折叠?



