请在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的理解是,你会用它来结合同一层级的两个spec,例如在(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?))))

在此,我指定了“Get”的取值可以是内层级别的值(一个包含“TableName”和“Key”为键的映射)以及“TransactItems”的取值可以是外层级别的值(一个包含“Get”作为键的映射数组或包含“Put”和“ConditionCheck”作为键的映射数组)。

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

选择指定了嵌套映射结构所需的部分(基于顶级模式,但也遵循底层模式,如果顶级键引用了模式)。

目前无法在选择选择中谈论映射到映射的集合的集合,尽管这是我们正在考虑的事情。我认为那是你询问的问题空间。
明白了,谢谢。
...