我们假设:
(defmacro testing (&optional var)
`(list 'this 'is
,@(when (consp var) `('a 'list))))
当被调用时:
>(testing 2)
(THIS IS)
>(testing (list 1 2))
(THIS IS A LIST)
这就是我想要的。但现在,当我传递一个列表参数时:
>(defparameter bla (list 1 2 3))
BLA
>(testing bla)
(THIS IS)
我想是因为宏会检查(consp bla)
其中 bla 是一个符号,而不是列表?我该如何防止这种情况?
Thanks
你可以这样做:
(defmacro testing (&optional var)
`(if (consp ,var)
'(this is a list)
'(this is)))
So var
将在运行时(而不是编译时)进行评估。var
在宏展开中只出现一次,但如果出现多次,则必须使用 gensym。
编辑:如果你不想打字'(this is)
两次,执行以下操作:
(defmacro testing (&optional var)
`(append '(this is) (when (consp ,var) '(a list))))
不要使用eval
,它很慢,而且完全没有必要。通过替换var
进入宏扩展后,自然会在运行时对其进行求值。如果您使用 eval,您将执行以下操作:
(eval (append '(list 'this 'is) (when (consp 'bla) '('a 'list))))
Every执行时,它将构建一个表示代码的列表,并在运行之前对其进行编译。 (希望这不是循环!)如果您只使用一个生成简单代码的宏(没有eval
),它只会编译一次。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)