在Common Lisp中展开&rest参数

7
假设我已经厌倦了一遍又一遍地写“format t …”,想要更少的按键。那么我可以写出以下代码:
(defun puts (fstring &rest vars)
  (format t fstring vars))

(puts "~a ~a" 1 2)

;; error message results, because vars became (1 2)

现在,vars已经被转换成了我传递的任何参数列表。它需要被“展开”为一个值列表。
这个问题的典型解决方案是什么?
2个回答

11
你可以使用 apply 来做到这一点:(apply #'format t fstring vars)vars 展开为 format 的单独参数。

谢谢。我总是遇到这个问题,但我永远记不住或弄清楚该怎么做。 - Paul Nathan

2
除了使用 apply,还可以使用宏来实现,在宏中你可以使用,@在反引号内拼接列表:
(defmacro puts (fstring &rest vars)
  `(format t ,fstring ,@vars))

1
我也尝试过,但是宏和我还不够熟练。 :-) - Paul Nathan
函数更受青睐,因为它们更容易使用。 - Rainer Joswig
@Rainer:我知道如果没有特定要求使用宏,应该优先选择函数,但在这个问题标题(扩展&rest参数)的上下文中,我认为backquotes对此有特殊支持,这一点值得注意。 - Rörd
1
当然,反引号只是LIST和相关函数的不同语法,通常与宏无关。您的反引号表达式与(list* 'format t fstring vars)相同。但是如果您有一个宏,就不能APPLY PUTS等操作。宏不适合这种情况。 - Rainer Joswig

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接