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

欢迎!有关本站如何运作的更多信息,请参阅关于页面。

+2 投票

重标记

在spec alpha 2中,如果我们定义了一个适用于未命名空间键的嵌套spec的s/schema的s/select,然后尝试使用s/valid?或s/exercise来使用它,我们会遇到异常。
s/valid 抛出“没有实现::conform方法”的错误,协议:#'clojure.alpha.spec.protocols/Spec未在类:clojure.lang.Keyword中找到;而s/exercise 则抛出“无法解析spec::foo”(其中:foo是未命名空间键)的异常。

一个例子可以更好地说明这个问题。

; Context
(s/def ::foo int?)
(s/def ::inner (s/schema [{:foo ::foo}]))
(s/def ::outer (s/schema [::inner]))

; Works as expected:
(s/exercise ::outer)
(s/exercise (s/select ::inner [*]))
(s/valid? (s/select ::inner [*]) {:foo 10})

; Fails with "Unable to resolve spec: :foo"
(s/exercise (s/select ::outer [*]))

; Fails with "No implementation of method: :conform* of protocol: #'clojure.alpha.spec.protocols/Spec found for class: clojure.lang.Keyword"
(s/valid? (s/select ::outer [*]) {::inner {:foo 10}})

2 个答案

+1 投票

我的第一反应是“Spec 2还不适宜使用,有多处错误”,正如Alex在其大多数关于Spec 2的问题中的回答所指出。

我本来期望::inner的语法是
(s/def ::inner (s/schema {:foo ::foo}))
根据维基文档说明,但这仍然不起作用(因此我回到了 "它是 Spec 2 当前许多bug之一")。

可以确认,截至2020年8月24日的Spec2 alpha版本中,该问题仍然存在(最新提交到master:d514b06b25c41a676b95afcc9bfac8ca34c5741e)。
我的解决方案是使用 s/keys 直至 schema 稳定。
0
...