2024 Clojure 状态调查!分享您的想法。

欢迎!请参阅关于页面了解如何使用本网站的更多信息。

0 投票
规范

在 Slack 上有人提问关于如何验证可选键的问题。我本来打算向他们指出s/keys的文档,但发现在可能需要一些澄清。

-------------------------
clojure.spec.alpha/keys
([& {:keys [req req-un opt opt-un gen]}])
Macro
  Creates and returns a map validating spec. :req and :opt are both
  vectors of namespaced-qualified keywords. The validator will ensure
  the :req keys are present. The :opt keys serve as documentation and
  may be used by the generator.

  The :req key vector supports 'and' and 'or' for key groups:

  (s/keys :req [::x ::y (or ::secret (and ::user ::pwd))] :opt [::z])

  There are also -un versions of :req and :opt. These allow
  you to connect unqualified keys to specs.  In each case, fully
  qualfied keywords are passed, which name the specs, but unqualified
  keys (with the same name component) are expected and checked at
  conform-time, and generated during gen:

  (s/keys :req-un [:my.ns/x :my.ns/y])

  The above says keys :x and :y are required, and will be validated
  and generated by specs (if they exist) named :my.ns/x :my.ns/y 
  respectively.

  In addition, the values of *all* namespace-qualified keys will be validated
  (and possibly destructured) by any registered specs. Note: there is
  no support for inline value specification, by design.

  Optionally takes :gen generator-fn, which must be a fn of no args that
  returns a test.check generator.

我曾以为会看到一些内容,表明如果:opt:opt-un指定的键存在,将根据这些键的规范进行验证。但事实上,它只是提到这些键作为文档使用。

这似乎需要一些澄清。

1 个答案

+1 投票

选择
最佳答案
 
最佳答案

此外,所有命名空间合格的键的值将由任何已注册的规范进行验证(可能还会进行解构)。

我读了这个,感觉有些微妙。它也让我想到以下内容可能是错误的,因为`::c`是一个已注册的、有命名空间的规范。

(s/def ::c pos-int?)
(s/valid? (s/keys :opt-un []) {:c "3"})

我认为唯一可以解释这一点的方法是,如果存在可选键,则会验证它们,而且这发生在验证所有命名空间限定键之后。
我认为我在这里有点傻,但我想这可能已经涵盖了。我被“命名空间限定键”这个词组的歧义弄糊涂了,这个词组指的是req、req-un、opt和opt-un向量中的键,而不是map中的键。无论如何,非常感谢这么晚的回答。
...