0

出于某种原因,以下规范确实说这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
4

2 回答 2

4

这与 无关spec,而与集合如何作为函数的行为有关。每当您使用集合作为函数来测试成员资格时,您都会遇到类似的误解。

当您传递spec一个函数时,它会将其用作谓词。集合是函数,其他任何实现clojure.lang.IFn. 作为函数,集合在其成员上表现为身份。其他一切都随之而来。集合绝不会被spec.

于 2017-05-24T15:36:20.123 回答
1

事实证明,给 Spec 的集合中不允许有虚假的东西,因为它使用集合本身作为函数来检查成员资格而不是contains?函数。正如我们在下面看到的,如果它是集合的成员,集合将返回给定的参数,否则返回 nil。

(#{:a :b :c false} :a)    ; => :a
(#{:a :b :c false} false) ; => false
(#{:a :b :c false} :d)    ; => nil

这当然是造成误解的原因。

contains为了让规范正常工作,我们必须手动将集合包装在 a中。

(spec/def ::a-thing #(contains? #{:a :b :c false} %))
于 2017-05-24T15:24:47.483 回答