地图规格

你可以通过指定地图中应存在哪些键来指定地图:

(clojure.spec/def ::name string?)
(clojure.spec/def ::age pos-int?)
(clojure.spec/def ::occupation string?)

(clojure.spec/def ::person (clojure.spec/keys :req [::name ::age ::occupation]))

(clojure.spec/valid? ::person {::name "john" ::age 25 ::occupation "programmer"})
;; => true

:req 是需要出现在地图中的键的向量。你可以指定其他选项,例如:opt,一个可选的键向量。

到目前为止,这些示例要求名称中的键是名称空间限定的。但是地图键不合格是很常见的。对于这种情况,clojure.spec 提供:req 和:对于不合格的密钥的 opt 等价物::req-un:opt-un。这是相同的例子,带有不合格的密钥:

(clojure.spec/def ::name string?)
(clojure.spec/def ::age pos-int?)
(clojure.spec/def ::occupation string?)

(clojure.spec/def ::person (clojure.spec/keys :req-un [::name ::age ::occupation]))

(clojure.spec/valid? ::person {:name "john" :age 25 :occupation "programmer"})
;; => true

注意:req-un 向量中提供的规范如何仍然合格。clojure.spec,在符合值时会自动确认地图中的非限定版本。

命名空间映射文字语法允许你简洁地通过单个命名空间限定映射的所有键。例如:

(clojure.spec/def ::name string?)
(clojure.spec/def ::age pos-int?)
(clojure.spec/def ::occupation string?)

(clojure.spec/def ::person (clojure.spec/keys :req [::name ::age ::occupation]))

(clojure.spec/valid? ::person #:user{:name "john" :age 25 :occupation "programmer"})
;;=> true

请注意特殊的 #:阅读器语法。我们遵循这个命名空间,我们希望限定所有地图键。然后将根据与提供的命名空间相对应的规范检查这些内容。