假设我有以下关键字数组
(def keys [::description ::url ::mailing-list])我想在两个规范中重用它;一个用于定义映射,另一个用于定义函数的可选参数。
(require '[clojure.spec :as spec])
(spec/def ::project-map
(spec/keys :opt-un keys))
(spec/def ::project-args
(spec/keys* :opt-un keys))问题是,keys和keys*被传递给引用的符号'keys,而不是它所引用的变量中的解析值。
因此,我的问题是:是否有可能像普通的lisp #.读取器宏那样在读取时解析键的值,或者是否需要重新定义宏来解析符号,如果它得到的是符号而不是列表文本?
发布于 2017-04-10 15:47:02
您还可以将它们包装在另一个宏中,因为宏负责如何计算它们的参数。
(defmacro def-both [name name* keys]
`(do (s/def ~name (s/keys :opt-un ~keys))
(s/def ~name* (s/keys* :opt-un ~keys))))
(user/def-both ::project-map ::project-args [::description ::url ::mailing-list])发布于 2017-04-10 12:54:51
您可以使用eval来构建一个半途而废的解决方案
(spec/def ::project-map
(eval `(spec/keys :opt-un ~keys)))
(spec/def ::project-args
(eval `(spec/keys* :opt-un ~keys)))这是在衣衫军松懈的时候提出的。
发布于 2021-09-10 22:54:33
我遇到了一个类似的问题,我试图动态注册规范。我遇到了麻烦,因为我没有传入文字关键字,所以解决方案是对宏的args进行评估,然后引用以下内容:
(def my-key ::this-is-a-test-key)
(defmacro define-spec [spec-key validator]
(let [local-key (eval spec-key)]
`(s/def ~local-key ~validator)))
(define-spec my-key int?)
;;testing it
(s/valid? my-key 123)
(s/valid? my-key "ASDASD")还值得注意的是,在cljs中,调用define-spec将返回nils,因为cljs不支持宏。
https://stackoverflow.com/questions/43321732
复制相似问题