clojure.set/intersection,根据其意图和文档,旨在对两个集合执行操作。然而,它有时允许(并在非集合参数上返回正确的操作)非集合参数。这产生了一些困惑,误解了非集合参数不应使用的意图。
以下是一个使用 Set 与 KeySeq 的示例
如果恰好存在交集,您将得到一个结果。这可能导致编写代码的人认为这是可以接受的,或者没有注意到他们使用了不兼容的数据类型。然而,一旦交集为空,就会产生一个适当的类型错误,即意外地因为 clojure.core/disj 的第一个参数应该是集合。
user=> (require '[clojure.set :refer [intersection]])
nil
user=> (intersection #{:key_1 :key_2} (keys {:key_1 "na"})) ; 此操作可行,但不应该
(:key_1)
user=> (intersection #{:key_1 :key_2} (keys {:key_3 "na"})) ; 此操作失败,因为 intersection 假设第二个参数是集合
ClassCastException clojure.lang.APersistentMap$KeySeq cannot be cast to clojure.lang.IPersistentSet clojure.core/disj (core.clj:1449)
(disj (keys {:key_1 "na"}) #{:key_1 :key_2}) ; intersection 做出的假设
ClassCastException clojure.lang.APersistentMap$KeySeq cannot be cast to clojure.lang.IPersistentSet clojure.core/disj (core.clj:1449)
对一个明显旨在用于特定类的库进行类型安全检查似乎是一件负责任的事情。它可以防止具有缺陷的代码不被知不觉地接受为正确,直到正确的数据出现并触发出错。