gpt4 book ai didi

clojure.spec 人类可读的形状?

转载 作者:行者123 更新时间:2023-12-02 14:22:13 28 4
gpt4 key购买 nike

使用 clojure.spec,有没有办法为嵌套映射定义更“人类可读”的规范?以下内容读起来不太好:

(s/def ::my-domain-entity (s/keys :req-un [:a :b])
(s/def :a (s/keys :req-un [:c :d]))
(s/def :b boolean?)
(s/def :c number?)
(s/def :d string?)

鉴于一致实体的形状类似于

{:a {:c 1 :d "hello"} :b false}

我的提示是,如果规范具有任何类型的嵌套映射或任何深层结构,那么它就会变得很难(呃)阅读……因为您在文件中上下追逐键,而它们不是“就位”声明.

相比之下,模式之类的东西允许更易读的嵌套语法,密切反射(reflect)实际的数据形状:

(m/defschema my-domain-entity {:a {:c sc/number :d sc/string} :b sc/bool})

这可以在 clojure.spec 中完成吗?

最佳答案

规范的值(value)主张之一是它不尝试定义实际的模式。它不将实体的定义与其组件的定义绑定(bind)。引用spec rationale :

Most systems for specifying structures conflate the specification of the key set (e.g. of keys in a map, fields in an object) with the specification of the values designated by those keys. I.e. in such approaches the schema for a map might say :a-key’s type is x-type and :b-key’s type is y-type. This is a major source of rigidity and redundancy.

In Clojure we gain power by dynamically composing, merging and building up maps. We routinely deal with optional and partial data, data produced by unreliable external sources, dynamic queries etc. These maps represent various sets, subsets, intersections and unions of the same keys, and in general ought to have the same semantic for the same key wherever it is used. Defining specifications of every subset/union/intersection, and then redundantly stating the semantic of each key is both an antipattern and unworkable in the most dynamic cases.

所以直接回答这个问题,不,spec 不提供这种类型的规范,因为它是专门这样设计的。您需要在类似模式的定义中牺牲一定程度的人类可读性,以获得更加动态、可组合、灵活的规范。

尽管这不是您的问题,但请考虑使用将实体的定义与其组件的定义分离的系统的好处。这是人为的,但请考虑定义一辆汽车(保持简单以节省空间,仅使用轮胎和底盘):

(s/def ::car (s/keys :req [::tires ::chassis]))

我们定义一次,我们就可以在上面放置我们想要的任何轮胎配置:

(s/def ::tires (s/coll-of ::tire :count 4))

(s/def ::tire (s/or :goodyear ::goodyear}
:michelin ::michelin))

(s/def ::goodyear #{"all-season" "sport" "value"})
(s/def ::michelin #{"smooth ride" "sport performance"})

(s/def ::chassis #{"family sedan" "sports"})

以下是不同的配置,但都是有效的汽车:

(s/valid? ::car {::tires ["sport" "sport" "sport" "sport"]
::chassis "sports"})

(s/valid? ::car {::tires ["smooth ride" "smooth ride"
"smooth ride" "smooth ride"]
::chassis "family sedan"})

这是人为的,但可以清楚地看到,将组件定义为独立于组件组合在一起形成的组件是有灵 active 的。轮胎有自己的规范,尽管它们是汽车的组成部分,但它们的规范并不是汽车的定义。它更冗长,但更灵活。

关于clojure.spec 人类可读的形状?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42346404/

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