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

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

0
Spec
编辑

尽管文档似乎表明这不应是注册的可用值,但我可以注册带有不可解符号的spec。这是安全的吗?它还会继续工作吗?

关于s/def文档说明,它接受第一个参数为“命名空间限定关键字或可解符号。”这比spec指南所述的范围更广,指南中说,“spec名称始终为完全限定的关键字。”

但我最近将一组spec从关键字更改为符号(完全限定但未绑定),一切似乎都正常运行,从s/valid?s/conform,到s/assert,以及在本地的s/keys等中引用定义。

这里有一个简化示例

user> (require '[clojure.spec.alpha :as s])
nil
user> (ns-resolve 'com.example 'foo)
Execution error at user/eval30383 (form-init8866507034262802929.clj:53).
No namespace: com.example found
user> (s/def com.example/foo string?)
com.example/foo
user> (s/valid? 'com.example/foo "x")
true
user> (s/valid? 'com.example/foo 42)
false
user> (s/valid? (s/keys :req ['com.example/foo]) {'com.example/foo "x"})
true
user> (ns-resolve 'com.example 'foo)
Execution error at user/eval30389 (form-init8866507034262802929.clj:62).
No namespace: com.example found
user> 

我猜测这是一个实例,其中实现略领先于文档,甚至更领先于指南。要么这样,要么也许我在理解“可解符号”的含义时犯了错误。感谢任何指导和提示!

1 答案

+2
 
最佳答案

注册表旨在保留两种类型的键:关键字(命名规范)和解析为功能规范的符号。由于后者的用途是功能规范,除非符号解析,否则它们不能真正有效地解析(因此文档如此)。

但是,我们在s/def时并没有验证符号是否可解析,实际上我们也不想这样做,因为这允许在引用的功能之前或之后定义规范。

您绝对不应该像这个示例那样直接使用符号调用s/def(这是允许的,因为s/fdef就是这样在底层工作的)。

...