我在玩着spec,其中一部分设计我不太理解。似乎没有一种很好的机制来表示“这个值同时满足一系列spec”。
开始时
(s/def :example/s1 vector?)
(s/def :example/s2 vector?)
(s/def :example/spec (s/and :example/s1 :example/s2))
(s/valid? :example/spec [1 2 3]) ; => true
然后将:example/s1
改为
(s/def :example/s1 (s/cat :a integer? :b integer? :c integer?))
现在
(s/valid? :example/spec [1 2 3]) ; => false
这使得我在试图调试一个spec的时候陷入了困境,那是一个糟糕的经历;我不想再次置身于那样的境地。如果spec更复杂,我甚至不知道如何开始,所以我想尽量避免那些在中间完全转换/适配数据的功能,除非这明显是必需的。
s/every
在基本情况下似乎不安全 - 尽管它叫这个名字,它并不检查spec对每个条目都是真的。我有一些函数会向长向量扩展新的条目,并且基于s/every
的spec将不会检查最可能包含bug的值。
我现在处于这样的地位,感觉到有压力要重新实现s/every
(使其全面)或者s/and
(使其验证但不适配)- 但是这让我有点困惑,因为我刚刚假设我想要的功能将是常见的用例。我错过了什么吗?为什么在spec中没有包含不适配的s/and
变体?