每次递归调用都会减少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替换为。前者更通用,但后者在某些实现中可能更快。svrefsimple vector
可以使用以下任一方法创建一个simple vector函数
(vector #'func-a #'func-b ...)
或者
#(func-a func-b ...)
A simple vectorof 函数也可以使用该make-array函数创建,但前提是:adjustable和:fill-pointer关键字参数未指定 or nil。