Lisp 反引号扩展列表中的一系列元素

Lisp 反引号扩展列表中的一系列元素,lisp,common-lisp,clisp,Lisp,Common Lisp,Clisp,假设我有一个struct(它的参数比这里显示的要多): 以及使用反引号定义一系列位置的关联列表: (defparameter *locations* `( (ASIA ,(make-location :name "Asia")) (AFRICA ,(make-location :name "Africa")) ) 这样可以很好地创建位置结构。问题是,我计划有很多地点,不仅仅是手工输入: (defparameter *locations* `( (ASIA ,(make-loca

假设我有一个struct(它的参数比这里显示的要多):

以及使用反引号定义一系列位置的关联列表:

(defparameter *locations* `(
  (ASIA ,(make-location :name "Asia"))
  (AFRICA ,(make-location :name "Africa"))
  )
这样可以很好地创建位置结构。问题是,我计划有很多地点,不仅仅是手工输入:

(defparameter *locations* `(
  (ASIA ,(make-location :name "Asia"))
  (AFRICA ,(make-location :name "Africa"))
  (LOC1 ,(make-location :name "Location 1"))
  ; Lots more...
  (LOC1024 ,(make-location :name "Location 1027"))
  )
这些额外位置中有许多具有类似参数,因此我可以定义一个“生成器函数”来创建它们的列表:

(defun generate-locations (symbol name count)
  (loop for i from 1 to count collect (list
    (read-from-string (format nil "~A~D" symbol i))
    (make-location :name name))))

;;; Creates list ((LOC1 #S(LOCATION :NAME "Location 1")) (LOC2 ...
(generate-locations "LOC" "Location " 1024)
然后我试着做一些类似的事情:

(defparameter *locations* `(
  (ASIA ,(make-location :name "Asia"))
  (AFRICA ,(make-location :name "Africa"))
  ,(generate-locations "LOC" "Location " 1024)
  )
不起作用,因为
GENERATE-LOCATIONS
返回一个列表,而不是一系列可以添加到列表中的元素。所以我试着
VALUES-LIST
it:

(defparameter *locations* `(
  (ASIA ,(make-location :name "Asia"))
  (AFRICA ,(make-location :name "Africa"))
  ,(values-list (generate-locations "LOC" "Location " 1024))
  )
这只会将第一个生成的位置添加到
*位置*
。我假设这是因为除了
values-LIST
中的第一个之外,所有返回值都被忽略


那么,如何正确地将一系列元素添加到
*位置*
GENERATE-LOCATIONS
应该是宏吗?如果是这样的话,它将如何构造?

您需要使用拼接取消报价操作符,
,@
。在您的示例中:

(defparameter *locations* `(
  (ASIA ,(make-location :name "Asia"))
  (AFRICA ,(make-location :name "Africa"))
  ,@(generate-locations "LOC" "Location " 1024)
  )

要使其工作,
生成位置
应返回一个列表
,@
会将每个项目拼接到周围的列表中,而不是将其作为单个项目插入。

@WilliamGaul您可以阅读更多信息。@JoshuaTaylor我不敢相信我没有看到该页面…必须学会使用hyperspec更多:p无论如何,谢谢您的资源@威廉高尔我只是为了完整才把它包括进去。反引号在规范中不太难找到,但如果您不能找到,一些非字母数字符号可能很难找到,例如,记住他们所称的“#”字符。例如,在搜索哈希符号管道时,如果幸运的话,您可能最终会找到。起初,我认为反报价可能也是一个棘手的案例。
(defparameter *locations* `(
  (ASIA ,(make-location :name "Asia"))
  (AFRICA ,(make-location :name "Africa"))
  ,@(generate-locations "LOC" "Location " 1024)
  )