every-kv 文档指出 "接受单独的键和值谓词,并作用于关联集合"。向量对 (associasive?) 返回 true,但目前不可用
user=> (s/conform (s/every-kv any? any?) [])
[]
user=> (s/conform (s/every-kv any? any?) [1 2 3])
:clojure.spec/invalid
user=> (s/conform (s/every-kv integer? string?) [])
[]
user=> (s/conform (s/every-kv integer? string?) ["x"])
:clojure.spec/invalid
另一个类似问题
(s/explain-data (s/every-kv int? int?) [{:a :b}])
UnsupportedOperationException nth 不支持此类型:PersistentArrayMap clojure.lang.RT.nthFrom (RT.java:903)
*原因:* 向量不应与 every-kv 一起使用。every-kv 和 every-impl 的组合假设传递给 every-kv 的集合可以提供映射条目的序列。在 explain 情况下,every-kv 创建的 ::kfn 用于使用键而不是元素索引创建更好的路径段。kfn 假设集合的元素可以调用 `(nth entry 0)` 在元素上。在上面的 explain 失败中,映射 {:a :b} 将在调用 nth 时抛出。
*建议:* 执行以下操作以更清楚地说明对 coll 元素为映射条目的要求
* 修改文档字符串,将其修改为 "seqs to map entries" 而不是 "is a map"
* 修改 kfn 以添加一个检查以确定元素是否是条目。如果是,则使用其键。如果不是,则使用元素(自己)的索引。在这种情况下,当传递条目时,将报告实际键;当传递不是条目的内容时,将报告非条目的集合基本索引。
修补后,explain-data 调用将提供一个有用的错误,而不是上面的异常。
user=> (s/explain-data (s/every-kv int? int?) [{:a :b}])
#:clojure.spec.alpha{:problems ({:path [], :pred vector?, :val {:a :b}, :via [], :in [0]})}
*补丁:* clj-2080-8.patch