这是示例代码:
(defun my-test (&rest values)
(macrolet ((my-macro (v)
`(list ,@v)))
(print values)
(my-macro values)))
(my-test 1 2 3 4)
;; The goal is to obtain : (1 2 3 4).
当我执行最后一行时,它会显示(1 2 3 4)
,然后函数将失败。
当我执行defun或尝试执行最后一行时,我得到以下警告/错误(分别):
; in: DEFUN MY-TEST
; (MY-PACKAGE::MY-MACRO VALUES)
; ==>
; (LIST . VALUES)
;
; caught ERROR:
; (LIST . VALUES) is not a proper list.
;
; compilation unit finished
; caught 1 ERROR condition
为什么会失败?
答案 0 :(得分:4)
宏转换代码,它对运行时值一无所知,只有文字代码。例如。
(cond (p1 e1) (p2 e2) (t e3))
变成
(if p1
e1
(if p2
e3))
我们真的不知道p1
在这一刻。现在看一下您的代码:
(defun my-test (&rest values)
(macrolet ((my-macro (v)
`(list ,@v)))
(print values)
(my-macro values)))
因此,在创建my-test
时会扩展宏。如果不能my-macro
,请问我如何(my-macro values)
扩展(list . values)
?
(list . values)
无效的Common Lisp,这是错误的根源。
您也许应该在没有宏的情况下执行此操作。例如。只需使用values
即可正常工作。要使用列表作为参数调用函数,可以使用apply
。要复制不需要的列表,可以使用copy-list
或copy-tree