请在 2024 年 Clojure 状态调查中分享您的看法!

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

+2
Libs
重标记

在 specs alpha 2 中,如果我们定义一个作为嵌套 spec 的 s/schema 的 spec(它本身也是一个 s/schema,但其键未命名空间),然后尝试使用 s/valid? 或 s/exercise,我们会得到异常
s/valid 抛出 *"没有为类:clojure.lang.Keyword 的协议:'#clojure.alpha.spec.protocols/Spec' 找到方法::conform",而 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
by

我的第一个反应是“Spec 2 还没有准备好使用,并且存在许多错误”,正如 Alex 在对该类问题的回答中所说。

根据wiki文档,我本以为 ::inner 的语法应该是
(s/def ::inner (s/schema {:foo ::foo}))
但这也不起作用(所以我回到“它是当前 Spec 2 中许多错误之一”)。

by
确认该问题在Spec2 alpha版本中仍然存在,截至2020-08-24(最新提交至master的commit:d514b06b25c41a676b95afcc9bfac8ca34c5741e)。
by
我的解决方案是使用s/keys直到架构稳定。
0
by
...