使用可变宏参数作为列表

Using variadic macro arguments as a list

我正在尝试编写一个宏,将多个表达式的 运行 次和 运行 比较成一堵墙。我的问题可以浓缩为以下代码:

(defmacro test-m [& exprs]
  `(map #(.toString %) ~exprs))

如果我这样称呼它 (test-m 1 2 3),我希望它会生成如下代码:

(map #(.toString %) [1 2 3])

完全正确。不幸的是,这实际上会导致错误:

ClassCastException java.lang.Long cannot be cast to clojure.lang.IFn helpers.general-helpers/eval663 (NO_SOURCE_FILE:76)

我能看到这可能发生的唯一方法是如果 & exprs 导致 (1 2 3),然后它将尝试将 1 作为函数调用,这显然是错误的。

如何映射宏中的可变参数列表?

我在写问题的时候弄明白了,所以我想我会 post 一个答案,以防将来其他人被困在这里。

参数列表需要先强制为列表表示,否则将被评估为表单。这可以像这样完成:

(defmacro test-m [& exprs]
  `(map #(.toString %) (list ~@exprs))

请注意 exprs 通过 @ 扩展并提供给 list。 (感谢@amalloy 的更正)。

显而易见的是回想起来,但它让我停滞了一段时间。希望这对某人有所帮助。