clojure:如何将名称空间作为宏参数传递?

时间:2016-12-01 17:59:27

标签: clojure macros namespaces clojure.spec

我正在尝试使用clojure.spec,我想我会编写一个宏来节省一些繁琐的输入: - )

我试图这样做:

(defmacro nup
    [pns pname punit]
    `(s/def :~pns/name (s/and #(string? %) #(= % ~pname)))
    `(s/def :~pns/unit (s/and #(string? %) #(= % ~punit))))

我已经尝试了多个版本,但我无法使名称空间替换工作。有任何想法吗? 毋庸置疑,宏不是我强大的一面。

1 个答案:

答案 0 :(得分:1)

你去了:

(defmacro nup
  [pns pname punit]
  `(do
    (s/def ~(keyword (str pns) "name") (s/and #(string? %) #(= % ~pname)))
    (s/def ~(keyword (str pns) "unit") (s/and #(string? %) #(= % ~punit)))))

(macroexpand-1
  '(nup ab :foo :bar))

s/def只是在规范的注册表中注册关键字。所以你根本不需要宏。只需使用一个功能,就容易多了。