【问题标题】:A Clojure Spec for a set with falsey values in them包含虚假值的集合的 Clojure 规范
【发布时间】:2017-05-24 15:24:47
【问题描述】:

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

【问题讨论】:

    标签: clojure clojure.spec


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

      事实证明,在给 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} %))
      

      【讨论】:

      • 不是这样。虚假的事情是允许的——它们只是不会产生你预期的结果。无论是 spec 还是其他地方,只要将包含错误值的集合用作谓词,都是如此。
      • 没有区别的区别。集合不应用作谓词。指导用户使用集合作为谓词是规范指南的错,而不是用户使用它们。
      • @Rovanion 这绝不是不鼓励使用集合作为规范谓词的理由。您的问题是关于仅适用于包含 nilfalse 的集合的极端案例——这在实践中很少见。
      • 我同意the spec Guide 有过错。但spec 本身不是。短语“除了nilfalse 可以解决它。
      猜你喜欢
      • 2018-05-22
      • 1970-01-01
      • 2017-06-13
      • 1970-01-01
      • 1970-01-01
      • 2017-03-27
      • 1970-01-01
      • 1970-01-01
      • 2012-09-19
      相关资源
      最近更新 更多