gpt4 book ai didi

macros - 普通口齿不清 : How to build a list in a macro with conditional splicing?

转载 作者:行者123 更新时间:2023-12-01 23:25:08 27 4
gpt4 key购买 nike

假设:

(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 是一个符号,而不是列表?我该如何防止这种情况?

谢谢

最佳答案

你可以这样做:

(defmacro testing (&optional var)
`(if (consp ,var)
'(this is a list)
'(this is)))

因此 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))))

每次 执行时,它都会构建一个表示代码的列表并在运行之前对其进行编译。 (希望这不是循环!)如果您只使用生成简单代码的宏(没有 eval),它只会编译一次。

关于macros - 普通口齿不清 : How to build a list in a macro with conditional splicing?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9214673/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com