如何将基于loop函数的LISP迭代式loadfile函数改写为递归实现?
递归重写LISP文件读取函数
当然可以用递归实现这个功能!我们可以把原来的迭代逻辑转化为递归思路:每次读取一行内容,然后递归处理文件剩余的部分,直到遇到EOF终止递归。
递归版本代码
(defun loadfile (filename) (with-open-file (stream filename) (labels ((read-lines () (let ((line (read-line stream nil 'eof))) (unless (eq line 'eof) (cons line (read-lines)))))) (read-lines))))
代码解释
- 我们在
with-open-file内部定义了一个局部递归函数read-lines,用来封装逐行读取的递归逻辑 - 每次调用
read-lines时,先尝试读取一行到line变量 - 基准情况(Base Case):如果
line等于'eof,就返回nil,直接终止递归 - 递归步骤:如果读取到有效行,就把当前行和
read-lines的递归调用结果用cons组合起来,最终会生成一个包含文件所有行的列表,和原loop版本里collect的效果完全一致
和原loop版本的对比
原版本用loop的for...until...collect做迭代式收集,递归版本则通过函数自身调用实现循环逻辑,两者最终功能完全相同——都会返回文件所有行组成的列表,且同样借助with-open-file自动处理文件流的开闭,不用担心资源泄漏问题。
内容的提问来源于stack exchange,提问作者Fred_2
相关产品推荐
相关产品推荐

