【发布时间】:2020-10-05 08:12:41
【问题描述】:
有以下两个规格:
(s/def ::x keyword?)
(s/def ::y keyword?)
(s/def ::z keyword?)
(s/def ::a
(s/keys :req-un [::x
::y]
:opt-un [::z]))
(s/def ::b
(s/map-of string? string?))
如何将::a 和::b 组合成::m 使以下数据有效:
(s/valid? ::m
{:x :foo
:y :bar
:z :any})
(s/valid? ::m
{:x :foo
:y :bar})
(s/valid? ::m
{:x :foo
:y :bar
:z :baz})
(s/valid? ::m
{:x :foo
:y :bar
:z "baz"})
(s/valid? ::m
{:x :foo
:y :bar
:t "tic"})
另外,我如何将::a 和::b 组合成::m 所以以下数据无效:
(s/valid? ::m
{"r" "foo"
"t" "bar"})
(s/valid? ::m
{:x :foo
"r" "bar"})
(s/valid? ::m
{:x :foo
:y :bar
:r :any})
两者都不是:
(s/def ::m (s/merge ::a ::b))
(s/def ::m (s/or :a ::a :b ::b))
工作(如预期),但有没有办法按照规范顺序的优先级匹配地图条目?
它应该工作的方式如下:
- 取值的所有映射条目(即映射)
- 将映射条目分成两组。一个确认
::a规范,另一个符合::b规范。 - 这两个子图应符合每个相关规范作为一个整体。例如,第一个分区应该有所有必需的键。
【问题讨论】:
-
为什么
{"r" "foo" "t" "bar"}无效?是否符合::b规范? -
它无效,因为它仅符合
::b规范。我想定义一个符合::a和::b的规范。例如::aa 需要:x和:y并且可选地,当:z存在时,它必须是keyword。此外,::m允许映射中的任意键,只要它们是字符串并且它们的值也是字符串。 -
这听起来不像 AND,因为 ::b 中的“所有键都必须是字符串”违反了 ::a 中的关键字。我还认为
:t "tic"是有效的。所以它要么是“:x,:y,也许是:z”或任何带有字符串键和值的东西。 -
@cfrick 非常感谢您的 cmets。如果你说,我没有清楚正确地阐述我的问题,你是绝对正确的。老实说,我不知道如何表达清楚。我希望我所包含的示例确实有助于理解我的需求。如果您能将我的问题重新表述得更清楚,我将不胜感激。
标签: clojure clojure.spec