目前,我必须将它们作为符号的文字列表输入:在let绑定中进行破坏。
(let [{:keys [title author]} arg-map]
(println title))
但我有一个我想要解构的关键字列表,我想在程序的其他地方使用它们。
我是否可以做一些宏观魔法,只需在let绑定中引用符号名称,而不必复制现有的向量,如果更改,我必须多次更新相同的列表。
(def valid-keys [:title :author])
(let [{:keys valid-keys} arg-map]
(println title))
感谢您的帮助。
答案 0 :(得分:2)
绝对
(def keywords [:title :author])
(defmacro with-valid-keys [m & forms]
(let [syms (map (comp symbol name) keywords)]
`(let [{:keys [~@syms]} ~m]
~@forms)))
如果你有一个关键字矢量,你可以轻松地将它们转换为符号并在let绑定中使用它们。从宏扩展中,您可以看到宏只生成带符号的let绑定。
(prn
(macroexpand-1 '(with-valid-keys {:title "hahaha"}
(println title))))
=> (clojure.core / let [{:keys [title author]} {:title“hahaha”}](println title))
(with-valid-keys
{:title "hahaha"}
(println title))
=>哈哈哈
要小心隐藏这样的绑定会带来一些问题:
name
内的with-valid-keys
函数,您将获得name的绑定值,而不是函数。