gpt4 book ai didi

clojure - 使用宏和doseq来生成spec

转载 作者:行者123 更新时间:2023-12-02 02:34:42 26 4
gpt4 key购买 nike

我发现自己写了很多这样的规范:

(s/def ::name string?)
(s/def ::logUri string?)
(s/def ::subnet (s/and string? #(> (count %) 5)))
(s/def ::instanceType string?)
...
(s/def ::key (s/and string? #(> (count %) 5)))
(s/def ::instanceCount string?)
(s/def ::bidPct string?)

即很多s/ands/def。这似乎是一种浪费。所以我决定编写一个宏来为我完成这个任务。像这样的东西:

(defmacro and-spec [validations]
(doseq [[keyname & funcs] validations]
`(s/def ~keyname (s/and ~@funcs))))

所以我可以做这样的事情:

(and-spec [[::name1 [string?]]
[::name2 [string? #(> (count %) 5)]]])

这将为我完成所有 s/def 的工作。不幸的是,上面的宏不起作用,但我不知道为什么。

(s/valid? ::name1 "asdf")
Execution error at emr-cli.utils/eval6038 (form-init17784784591561795514.clj:1).
Unable to resolve spec: :emr-cli.utils/name1

这项工作的较小版本:

(defmacro small-and-spec-works [key-name validations]
`(s/def ~key-name (s/and ~@validations)))
=> #'emr-cli.utils/tsmall
(and-spec-small-works ::mykey [string?])
=> :emr-cli.utils/mykey
(s/valid? ::mykey "asdf")
=> true

但是当我引入 let 绑定(bind)时,事情就开始变得奇怪了:

(defmacro small-and-spec [validation]
(let [[key-name & valids] validation]
`(s/def ~key-name (s/and ~@valids))))
=> #'emr-cli.utils/small-and-spec
(small-and-spec [::mykey2 [string?]])
=> :emr-cli.utils/mykey2
(s/valid? ::mykey2 "asdf")
Execution error (IllegalArgumentException) at emr-cli.utils/eval6012 (form-init17784784591561795514.clj:1).
Key must be integer
  1. 如何使 doseq 宏发挥作用?
  2. small-and-spec 出了什么问题,导致出现 Key must be integer 错误?

最佳答案

(defmacro and-spec [defs]
`(do
~@(map (fn [[name rest]]
`(s/def ~name (s/and ~@rest))) defs)))

doseq 用于副作用。它总是返回nil

关于clojure - 使用宏和doseq来生成spec,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64498602/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com