Macros 在Clojure宏中引用基于~和~@的选项

Macros 在Clojure宏中引用基于~和~@的选项,macros,clojure,Macros,Clojure,我有两个不同的Clojure宏,但根据操作(~@和~),我需要引用输入或不引用输入 (defmacro make2 [t] `(list 1 ~@t)) (defmacro make3 [t] `(list 1 ~t)) (make2 (1 2 3)) -> (1 1 2 3) (make3 '(1 2 3)) -> (1 (1 2 3)) 为什么会这样?我可以猜测,对于宏,参数不会被计算(这就是make2不会导致错误的原因)。然而,在得到这些论点之后,我不确定处理

我有两个不同的Clojure宏,但根据操作(~@和~),我需要引用输入或不引用输入

(defmacro make2 [t]
  `(list 1 ~@t)) 

(defmacro make3 [t]
  `(list 1 ~t))

(make2 (1 2 3)) -> (1 1 2 3)

(make3 '(1 2 3)) -> (1 (1 2 3))
为什么会这样?我可以猜测,对于宏,参数不会被计算(这就是make2不会导致错误的原因)。然而,在得到这些论点之后,我不确定处理它们的逻辑

(macroexpand-1 '(make2 (1 2 3)))
;; ==> (clojure.core/list 1 1 2 3)

(macroexpand-1 '(make3 (1 2 3)))
;;==> (clojure.core/list 1 (1 2 3))
~@
将列表
(1 2 3)
拼接到表达式
(列表1…
)中,然后计算结果表达式,即使用参数
1 2 3
计算函数
list
。Clojure会计算每个参数,当然,数字会自行计算

~
只需将参数
(1 2 3)
作为第二个参数插入
(列表1…
),然后计算整个表达式,并将每个参数计算到
列表中。当它这样做时,Clojure看到在第二个参数中有一对不带引号的括号,并假设左括号后面的第一个表达式是一个函数(或宏)。也就是说,Clojure假设
1
的内部实例是一个函数,而不是。这就是为什么你会有例外

ClassCastException java.lang.Long cannot be cast to clojure.lang.IFn ...
也就是说长整数不能转换成函数