gpt4 book ai didi

clojure - 使用 clojure.spec 进行强制惯用吗?

转载 作者:行者123 更新时间:2023-12-04 00:58:05 24 4
gpt4 key购买 nike

我已经看到使用 clojure conformers 来强制各种 gists 中的数据,但也有一个印象(我不记得在哪里)强制(例如如下)不是 conformers 的惯用用法。

(s/def :conformers/int
(s/conformer (fn [x]
(cond
(integer? x) x
(re-matches #"\d+" x) (edn/read-string x)
:else :cljs.spec.alpha/invalid))))

(s/def :data.subscription/quantity :conformers/int)

(s/def :data/subscription (s/keys :req-un [:data.subscription/quantity]))

以上是否是单调的/无意的?如果是这样,什么是合适的/惯用的用法。预期用途的边界在哪里?

最佳答案

更新:

现在我已经发布了一个库来处理这个问题,请查看:https://github.com/wilkerlucio/spec-coerce

您可以将规范用于强制,但重要的是您还拥有它的非强制版本。如果你对你的规范强制强制,你会同时做两件事,违反 SRP。所以建议有一个简单的验证,然后你可以在它上面再做一个,所以以后你可以选择是使用强制版本还是简单验证。

另一种选择(我更喜欢)是让强制引擎基于并行运行的规范。如果您查看规范如何从规范 ( check here ) 推断生成器,您会发现您可以使用规范形式推导出其他东西,因此其他东西可以成为您的强制引擎。

我写了一篇文章,我解释了如何做到这一点,你可以在这里找到它(只是跳到强制规范部分):https://medium.com/@wilkerlucio/implementing-custom-om-next-parsers-f20ca6db1664

从文章中提取的代码供引用:

(def built-in-coercions
{`int? #(Long/parseLong %)
`nat-int? #(Long/parseLong %)
`pos-int? #(Long/parseLong %)
`inst? clojure.instant/read-instant-timestamp})

(defn spec->coerce-sym [spec]
(try (s/form spec) (catch Exception _ nil)))

(defn coerce [key value]
(let [form (spec->coerce-sym key)
coerce-fn (get built-in-coercions form identity)]
(if (string? value)
(coerce-fn value)
value)))

这里还有一个更详细的版本(只是代码),它包括一个辅助注册表,因此您可以设置特定的强制器以匹配相同的规范关键字: https://gist.github.com/wilkerlucio/08fb5f858a12b86f63c76cf453cd90c0

这样您就不会强制执行强制,使您的验证更快,并让您更好地控制何时强制(这通常应该只发生在系统的边界)。

关于clojure - 使用 clojure.spec 进行强制惯用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45188850/

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