只是为了给Arthur的答案提供一个平衡点:conj甚至更早定义(名称conj出现在core.clj的第82行vsp44的disj和1429的disoc),但适用于所有Clojure集合类型. :-)显然它不使用协议 – 相反它使用常规Java接口,就像大多数Clojure函数一样(事实上我相信目前Clojure中唯一使用协议的“核心”功能是reduce / reduce-kv ).
我猜想这是由于一种美学选择,并且实际上可能与地图支持结合的方式有关 – 他们支持disj,人们可能期望它采用可以传递给conj的相同参数,这将是问题:
;; hypothetical disj on map
(disj {:foo 1
[:foo 1] 2
{:foo 1 [:foo 1] 2} 3}
}
{:foo 1 [:foo 1] 2} ;; [:foo 1] similarly problematic
)
应该返回{},{:foo 1 [:foo 1] 2}还是{{:foo 1 [:foo 1] 2} 3}? conj愉快地接受[:foo 1]或{:foo 1 [:foo 1] 2}作为地图上的东西. (与两个映射参数合并意味着合并;实际上合并是根据conj实现的,添加了对nil的特殊处理).
因此,为地图设置dissoc可能是有意义的,因此很明显它会删除一个键,而不是“可以联合的东西”.
现在,理论上可以使用dissoc来处理集合,但是也许有人可能会期望它们也支持assoc,这可能说得不合理.可能值得指出的是,向量确实支持assoc而不是dissoc,所以这些并不总是在一起;这里肯定存在一些审美紧张.