出于某种原因,以下规范确实说false
不是有效的::a-thing
,即使它是给定集的一部分。
(require '[clojure.spec.alpha :as spec])
(spec/def ::a-thing #{:a :b :c false})
(spec/valid? ::a-thing :a) ; => true
(spec/valid? ::a-thing :d) ; => false
(spec/valid? ::a-thing false) ; => false
答案 0 :(得分:4)
这与spec
无关,而与集合如何表现为函数有关。每当您使用集合作为测试成员资格的函数时,您将会遇到类似的误解。
当您通过spec
函数时,它会将其用作谓词。集合是函数,就像实现clojure.lang.IFn
的任何其他函数一样。作为函数,集合在其成员上表现为身份。一切都随之而来。 spec
不会特意处理集合。
答案 1 :(得分:1)
事实证明,Spec中给出的集合中不允许有虚假的东西
因为它使用集合本身作为检查成员资格的函数而不是
contains?
函数。正如我们在下面看到的,一组将返回
给定参数,如果它是集合的成员,否则为nil。
(#{:a :b :c false} :a) ; => :a
(#{:a :b :c false} false) ; => false
(#{:a :b :c false} :d) ; => nil
这当然是造成误解的原因。
我们必须自己手动将该集合包装在contains
中,以使规范正常运行。
(spec/def ::a-thing #(contains? #{:a :b :c false} %))