【问题标题】:Clojure.spec "or" equivalent of "s/and"Clojure.spec “或”等价于“s/and”
【发布时间】:2018-05-06 18:14:37
【问题描述】:

我很喜欢与clojure.spec 合作;它有助于发现更接近原因的数据错误。目前我正在使用它来验证对 Web 服务器请求的响应,但我在 clojure.spec 操作的语法上遇到了困难,该操作允许两种不同的地图结构响应。

在我的数据中,网络服务器请求有两种可能的响应:

{:assignment "1232123"}

{:no-more-assignments true}

我可以使用multi-spec,但这对于一些简单的事情来说似乎很冗长,例如为每种情况设置一个规范并将规范定义为:

(s/def ::response
  (s/or ::case-1 ::case-2))

是否有一些我忽略的语法或者我需要使用multi-spec

【问题讨论】:

  • 为什么不能使用or

标签: clojure clojure.spec


【解决方案1】:

您可以将orandkeys 一起使用:

(s/def ::assignment string?)
(s/def ::no-more-assignments boolean?)
(s/def ::response
  (s/keys :req-un [(or ::assignment ::no-more-assignments)]))

(s/explain ::response {:assignment "123"})
;; Success!
(s/explain ::response {:foo true})
;; val: {:foo true} fails spec: :sandbox.so/response predicate: (or (contains? % :assignment) (contains? % :no-more-assignments))

【讨论】:

  • 行得通!谢谢。如果 ::asignment 是一个映射而不是一个字符串呢?当我定义时它失败了: (s/de​​f ::assignment (s/keys :req-un [::id ::reason]))
  • @frank 我不确定发生了什么,但无论::assignment 规范是什么,这都应该有效。你能详细说明它现在是如何失败的吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-08-04
  • 2011-04-03
  • 1970-01-01
  • 2017-12-09
  • 2014-02-07
  • 2010-09-23
  • 2015-10-22
相关资源
最近更新 更多