Macros 如何将列表更改为Clojure宏中的代码?
我有以下宏:Macros 如何将列表更改为Clojure宏中的代码?,macros,clojure,clojureql,Macros,Clojure,Clojureql,我有以下宏: (defmacro ss [x] `(clojureql.core/select (clojureql.core/table db "users_table") (clojureql.core/where ~x) ) ) (macroexpand '(ss '(= :type "special"))) :但它产生: (clojureql.core/select (clojureql.core/table oe.db.dbcore/db "use
(defmacro ss [x]
`(clojureql.core/select
(clojureql.core/table db "users_table")
(clojureql.core/where ~x)
)
)
(macroexpand '(ss '(= :type "special")))
:但它产生:
(clojureql.core/select (clojureql.core/table oe.db.dbcore/db "users_table") (clojureql.core/where '(= :type "special")))
:而不是:
(clojureql.core/select (clojureql.core/table oe.db.dbcore/db "users_table") (clojureql.core/where (= :type "special")))
:我意识到问题是我正在传递一个列表'(=:键入“special”),但是我如何才能在宏中取消引用它
更新:
多亏了米凯拉的回答,我终于做到了:
(defn ss [x]
(clojureql.core/select
(clojureql.core/table db "users_table")
x
)
)
(macroexpand '(ss (eval `(clojureql.core/where ~'(= :type "special")))))
:尽管输出略有不同,但其工作原理与预期一致:
(ss (eval (clojure.core/seq (clojure.core/concat (clojure.core/list 'clojureql.core/where) (clojure.core/list '(= :type "special"))))))
在我看来,您将错误的内容传递给了macroexpand:您可能应该使用:
(macroexpand '(ss (= :type "special")))
i、 e.在开始时只需要一个引号就可以引用整个表达式。不能将运行时参数传递给宏,因为前者仅在-well-runtime时已知,而后者已在-well-compile时展开和编译 你必须使用一个函数
(defn get-users-by-type
[t]
(cql/select
(cql/table db "users_table")
(cql/where (= :type t))))
在这种情况下,我使用了
eval
。只需将~x改为~(eval x)。但我不知道,可能还有另一种解决方案,或者你只是拼错了(=:type“special”)。当我使用eval时,我得到:(clojureql.core/select(clojureql.core/table oe.db.dbcore/db“users_table”)(clojureql.core/where(clojure.core/eval quote(:type“special”))这真的很奇怪,对我来说eval
正在工作(我试过了(defss[x]`(*3~(eval x))(宏扩展(ss'(+12)))。但是如果代码扩展为(quote(:type“special”),那么我只找到一个解决方案:使用~(second x)。但我不知道为什么我不喜欢它我正在使用“(=:type“special”),因为它在我的程序中作为一个参数传递,因为在Clojure中如果没有“Hmmm不太确定您的意思”我就无法传递(=:type“special”)。。。是否尝试在运行时使用eval展开宏?如果是这样,您可以使用(eval`(ss~parameter))Zubair:quote
引用其整个参数来运行该命令。你试过米凯拉的建议吗?是的,成功了,谢谢米凯拉!我已经更新了问题,以显示最终的效果。如果(cadr xx)
足够(只要始终引用参数),为什么要使用eval
?