除了使用 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
函数产生了我们想要的输出。
下一步是准备列表中的数据以在图表中显示。