请在2024年Clojure调查!中分享您的想法。

欢迎!请查看关于页面,了解更多关于本站点如何工作的信息。

+1 投票
Spec

我在使用Spec 2时遇到的一个问题。

(s/def ::number      number?)
(s/def ::boolean     boolean?)
(s/def ::schema      (s/schema [::number ::boolean]))
(s/def ::only-number (s/select ::schema [::number]))
(s/def ::this-works  (s/keys :req [::only-number]))
(s/def ::this-fails  (s/schema [::only-number]))
Execution error (AssertionError) at clojure.alpha.spec.impl/schema-impl (impl.clj:422).
Assert failed: (every? (fn* [p1__6948#] (if-let [sp (s/get-spec p1__6948#)] (not (select? sp)) true)) ks)

我创建了这个示例来复制我在创建AWS DynamoDB REST API的包装器时遇到的错误。

1 答案

+1 投票

不是,这不支持。可以使用s/union来组合模式。

https://github.com/clojure/spec-alpha2/wiki/Schema-and-select


编辑
我对s/union的理解是,您将使用它来组合处于相同层次级别的两个规格,如(s/union ::user/private ::user/public)。

我所需要的是一个像这个JSON结构一样的层次结构
{"TransactItems": [{"Get": {"TableName": "string", "Key": "string"}}]}

(s/def ::transact-schema (s/schema [::TableName ::Item ::Key ::ConditionExpression]))
(s/def ::Get                          (s/select ::transact-schema [::TableName ::Key]))
(s/def ::ConditionCheck  (s/select ::transact-schema [::TableName ::Key ::ConditionExpression]))
(s/def ::Put                          (s/select ::transact-schema [::TableName ::Item]))

(s/def ::TransactGetItem      (s/schema [::Get]))
(s/def ::TransactWriteItem  (s/schema [::ConditionCheck ::Put]))
(s/def ::TransactItems
    (s/or :get     (s/coll-of ::TransactGetItem :kind vector?)
              :write (s/coll-of ::TransactWriteItem :kind vector?)))

这里我指定了内部层“获取”的值可以是一个包含“TableName”和“Key”作为键的映射,以及外部层“TransactItems”的值可以是一个包含“Get”作为键的映射数组,或者是一个包含“Put”和“ConditionCheck”作为键的映射数组。

来源:https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TransactGetItems.html
by
模式是键的集合。联合将模式(键集合)组合成一个更大的键集合。它们没有嵌套,也不表示层次结构。

选择指定了嵌套映射结构所需的部分(基于顶层模式,但也可以根据顶层键引用的模式指定的低级模式)。

当前无法在选择选择中谈论映射的映射的集合,尽管这是我们在考虑的事情。我认为这是你提出的问题域。
by
明白了,谢谢。
...