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不能转换到clojure.lang.IPersistentSet clojure.core/disj (core.clj:1449)
(disj (keys {:key_1 "na"}) #{:key_1 :key_2}) ;intersection所做的假设
ClassCastException clojure.lang.APersistentMap$KeySeq不能转换到clojure.lang.IPersistentSet clojure.core/disj (core.clj:1449)
对一个明显是为特定类型设计的库执行类型安全检查似乎很负责任。它可以防止 bug 代码被无意中接受为正确,直到正确的数据出现并踩中陷阱。