rest 是一个与first 配对的访问器函数,为您提供第一个元素和列表的其余部分。 rest 与 cdr 相同。
&rest 是一个 lambda list keyword,它会在其后面的变量名中删除剩余的参数。
你真的在寻找apply。想象一下,我创建了一个可以接受 0 个或多个数字参数并将它们相加的函数:
(defun add (&rest numbers)
(apply #'+ numbers))
Apply 可以接受两个以上的参数。第一个是要调用的函数,除了最后一个之外,都是放在最后一个参数元素前面的额外参数。您可以保证实现支持 50 个参数,或者在特定实现支持超过 50 个的特定实现中,函数可以接受的参数数量最多。
(apply #'+ 1 2 '(3 4 5)) ; ==> 15
现在通过&rest 和apply 进行递归会导致代码效率低下,因此您应该使用高阶函数、循环宏或创建助手:
;; higher order function
(defun fetch-indexes (a &rest indexes)
(mapcar (lambda (i) (nth i a)) indexes))
;; loop macro
(defun fetch-indexes (a &rest indexes)
(loop :for i :in indexes
:collect (nth i a)))
;; helper function
(defun fetch-indexes (a &rest indexes)
(labels ((helper (indexes)
(if (endp indexes)
'()
(cons (nth (first indexes) a)
(helper (rest indexes))))))
(helper indexes)))
;; test (works the same with all)
(fetch-indexes '(a b c d) 2 3 0 1)
; ==> (c d a b)
应避免在递归中使用 apply,但我将展示它是如何完成的。
(defun fetch-indexes (a &rest indexes)
(if (endp indexes)
'()
(cons (nth (first indexes) a)
(apply #'fetch-indexes a (rest indexes)))))
在您的示例中,您有嵌套列表。为了使它起作用,您还需要将其展平。我还没有这样做,所以这些支持一个适当的元素列表。