除了使用 while 循环外,你还可以通过递归来处理文件列表中的每个文件。一个递归版本的 lengths-list-many-files 很短而简单。
递归函数具有通常的部分:再次执行测试、下一步表达式和递归调用。再次执行测试确定函数是否应该再次调用自身,如果 list-of-files 包含任何剩余元素,它将调用自身;下一步表达式将 list-of-files 重置为其自身的 CDR,所以最终列表将为空;递归调用在较短的列表上调用自身。整个函数比这个描述还要短!
(defun recursive-lengths-list-many-files (list-of-files)
"返回 LIST-OF-FILES 中每个 defun 的长度列表。"
(if list-of-files ; 再次执行测试
(append
(lengths-list-file
(expand-file-name (car list-of-files)))
(recursive-lengths-list-many-files
(cdr list-of-files)))))
简而言之,该函数返回第一个 list-of-files 的长度列表,附加到对其余 list-of-files 调用自身的结果上。
这里是对 recursive-lengths-list-many-files 的测试,以及在每个文件上分别运行 lengths-list-file 的结果。
如果需要,安装 recursive-lengths-list-many-files 和 lengths-list-file,然后评估以下表达式。您可能需要更改文件的路径;这些路径在此 Info 文件和 Emacs 源代码位于其习惯位置时有效。要更改表达式,将其复制到 *scratch* 缓冲区,编辑它们,然后评估它们。
结果在 ‘⇒’ 之后显示。(这些结果是针对 Emacs 版本 22.1.1 的文件;来自其他版本的 Emacs 的文件可能会产生不同的结果。)
(cd "/usr/local/share/emacs/22.1.1/")
(lengths-list-file "./lisp/macros.el")
⇒ (283 263 480 90)
(lengths-list-file "./lisp/mail/mailalias.el")
⇒ (38 32 29 95 178 180 321 218 324)
(lengths-list-file "./lisp/hex-util.el")
⇒ (82 71)
(recursive-lengths-list-many-files
'("./lisp/macros.el"
"./lisp/mail/mailalias.el"
"./lisp/hex-util.el"))
⇒ (283 263 480 90 38 32 29 95 178 180 321 218 324 82 71)
recursive-lengths-list-many-files 函数产生了我们想要的输出。
下一步是准备列表中的数据以在图表中显示。