每次递归调用都会减少kols
参数,直到它变为nil
. 何时kols
变为nil
您应该终止递归,因此您应该为终止条件添加测试(即,对于空列表):
(defun foo (funcs order)
(unless (endp order)
(funcall (nth (first order) funcs))
(foo funcs (rest order))))
我建议一个更易读的解决方案(它也更可取,因为 ANSI Common Lisp 标准不强制实现执行尾调用优化):
(defun foo (funcs order)
(loop for n in order do (funcall (nth n funcs))))
在前面的示例中,我假设您运行函数是为了它们的副作用,而不是返回值。
编辑 1
正如 Vatine 所指出的,使用nth
和 列表来提供随机访问的集合对性能不利,因此将函数存储在 a vector
(即一维array
)而不是列表中可能更值得。所以,假设funcs
是一个vector
函数,函数可以定义如下:
(defun foo (funcs order)
(loop for n in order do (funcall (aref funcs n))))
此外,如果函数数组是(词汇表条目) ,我们可以aref
替换为。前者更通用,但后者在某些实现中可能更快。svref
simple vector
可以使用以下任一方法创建一个simple vector
函数
(vector #'func-a #'func-b ...)
或者
#(func-a func-b ...)
A simple vector
of 函数也可以使用该make-array
函数创建,但前提是:adjustable
和:fill-pointer
关键字参数未指定 or nil
。