我有一个简单的问题 鉴于规范def,我想使用相同的规范,但仅作为一个可变的变体。
E.g。
(s/def ::uuid uuid?)
(s/def ::problem-spec (s/keys :req-un [::uuid]))
(s/def ::nilable-problem-spec (s/keys :req-un [::uuid])) ; <- (or nil ::uuid)
; what I expect
(s/valid? ::uuid #uuid "9494a3e0-7ef0-4b3f-b539-bd7f7f4f0181") ; true
(s/valid? ::uuid nil) ; false
(s/valid? ::problem-spec {:uuid #uuid "9494a3e0-7ef0-4b3f-b539-bd7f7f4f0181"}) ; true
(s/valid? ::problem-spec {:uuid nil}) ; false
(s/valid? ::nilable-problem-spec {:uuid #uuid "9494a3e0-7ef0-4b3f-b539-bd7f7f4f0181"}) ; true
(s/valid? ::nilable-problem-spec {:uuid nil}) ; true
答案 0 :(得分:2)
由于您已将::uuid
定义为无法使用,因此您无法在地图/键集中使用::uuid
键作为nilable值。这是有意的 - 规范中的合格密钥是全局定义的。
在这种情况下,您可以将::uuid
规范为nillable,然后限制密钥集的非可终止版本:
(s/def ::uuid (s/nilable uuid?))
(s/def ::problem-spec (s/and (s/keys :req-un [::uuid])
#(some? (:uuid %))))
(s/def ::nilable-problem-spec (s/keys :req-un [::uuid])) ;; as previously
或者,由于您在地图中处理非限定键,因此您还可以定义两个具有不同语义的不同限定uuid
关键字:
(s/def :nillable/uuid (s/nilable uuid?))
(s/def :non.nil/uuid uuid?)
(s/def ::problem-spec (s/keys :req-un [:non.nil/uuid])))
(s/def ::nilable-problem-spec (s/keys :req-un [:nillable/uuid]))