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)
对明显针对特定类型的库强制类型安全性是负责任的做法。它可以防止错误代码在不知情的情况下被认为是正确的,直到正确的数据出现踩到陷阱。