如何获得 Clojure 规范作为对象?

How can I get a Clojure Spec as an object?

我想查看代表 Clojure 规范的数据结构。

如何获取和查看它?

例如。给出

(s/def ::myspec (s/keys :opt-un [::x ::y]))

我想打印 myspec 的内部表示。

您可以使用 s/form 其中 "return[s] the spec as data":

(s/form ::myspec)
=> (clojure.spec.alpha/keys :opt-un [:user/x :user/y])

s/describe同一事物的缩写版本:

(s/describe ::myspec)
=> (keys :opt-un [:user/x :user/y])

这两者最终都依赖于Spec协议的describe*方法:

(defprotocol Spec
  (conform* [spec x])
  (unform* [spec y])
  (explain* [spec path via in x])
  (gen* [spec overrides path rmap])
  (with-gen* [spec gfn])
  (describe* [spec]))

所以每个规格 type 负责描述自己。例如,地图规范实现只是从它的初始输入中重建它的文字定义,如下所示:

(describe* [_] (cons `keys
                      (cond-> []
                              req (conj :req req)
                              opt (conj :opt opt)
                              req-un (conj :req-un req-un)
                              opt-un (conj :opt-un opt-un))))