every-kv 文档说明 "需要独立的关键字和值前缀,并在关联集合上工作"。向量对关联?返回 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 的集合可以提供映射项的序列。在解释的情况下,由 every-kv 创建的 ::kfn 用于使用键而不是元素索引来创建更好的路径段。kfn 假设集合的元素可以调用 `(nth entry 0)` 来调用元素。在上面的解释失败中,映射 {: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