我有一个记录,对于此规范,我想生成值但确保当前金额不超过最大金额。 简化的规范可能是:
(s/def ::max-amt (s/and number? #(<= 0 % 1e30)))
(s/def ::cur-amt (s/and number? #(<= 0 % 1e30)))
(s/def ::loan (s/cat :max-amt ::max-amt
:cur-amt ::cur-amt))
我知道s/and
规范中我可以::loan
,但我想要这样的内容:
(s/def :loan (s/cat :max-amt ::max-amt
;; not a real line:
:cur-amt (s/and ::cur-amt #(< (:cur-amt %) (:max-amt %)))))
这种类型的约束是否可用于规范?
注意:我知道我可以用0到1之间的数字替换cur-amt,它代表小数部分,但后来我修改数据以适应代码而不是其他方式arround 。我不在这里控制实际应用程序中的数据源。
答案 0 :(得分:3)
这应该有效(改编自this discussion):
(s/def ::loan (s/and (s/keys :req [::cur-amt ::max-amt])
(fn [{:keys [::cur-amt ::max-amt]}]
(< cur-amt max-amt))))
(s/conform ::loan {:cur-amt 50 :max-amt 100}) ; => {:cur-amt 50 :max-amt 100}
(s/conform ::loan {:cur-amt 100 :max-amt 50}) ; => :clojure.spec/invalid
或者,如果你想坚持s/cat
:
(s/def ::loan (s/and (s/cat :cur-amt ::cur-amt
:max-amt ::max-amt)
(fn [{:keys [cur-amt max-amt]}]
(< cur-amt max-amt))))
(s/conform ::loan [50 100]) ; => [50 100]
(s/conform ::loan [100 50]) ; => :clojure.spec/invalid