我试图编写一个宏来比较多个表达式的运行时间,然后碰壁。我的问题可以归结为以下代码:
(defmacro test-m [& exprs]
`(map #(.toString %) ~exprs))
如果我这样称呼我(test-m 1 2 3)
,我希望这会产生类似于以下内容的代码:
(map #(.toString %) [1 2 3])
这是完全有效的。但是不幸的是,这实际上导致了一个错误:
无法将ClassCastException java.lang.Long强制转换为clojure.lang.IFn helpers.general-helpers / eval663(NO_SOURCE_FILE:76)
我看到这种情况的唯一方法是,如果& exprs
结果为(1 2 3)
,则将尝试1
作为函数调用,这显然是错误的。
如何在宏中映射可变参数列表?
我在写问题时就弄清楚了,所以我想我会发布一个答案,以防将来有人被卡在这里。
参数列表首先需要强制设置为列表表示形式,否则将被视为一种形式。可以像这样完成:
(defmacro test-m [& exprs]
`(map #(.toString %) (list ~@exprs))
请注意,exprs
通过扩展了@
,并赋予list
。(感谢@amalloy进行更正)。
回想起来很明显,但它使我停了一会儿。希望这对某人有帮助。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句