为了有希望在这个讨论中增加一些清晰度,在Java中,通常会覆盖hashCode和equals.例如,您正在尝试跟踪具有名称但可能还有昵称的员工.目标是确保这些员工不会重复.在这种情况下,我会覆盖equals并hashCode只查看员工的ID.当这些员工进入Set数据结构时,它们不会重复.在Clojure中,您可以这样做:
(deftype Employee [name id]
Object
(equals [a b] (= (.id a) (.id b)))
(hashCode [this] (.hashCode (.id this)))
(toString [this] (.name this)))
(def vince (Employee. "Vince" 42))
(def vincent (Employee. "Vincent" 42))
(def tony (Employee. "Tony" 2))
(into #{} [vince vincent tony])
Run Code Online (Sandbox Code Playgroud)
但是你可能希望采用"纯Clojure"数据结构解决方案而不是去哈希码,等于Java互操作之路.
这并不是 clojure 集合重写了equals;而是 clojure 集合重写了 equals。覆盖 equals 几乎发生在你做一些有趣的事情的任何地方。Clojure 类型提供了 equals 的实现,旨在使整个语言保持一致(可以说以 Java 的 equals 的使用方式)。这意味着“相等”的事物应该是集合中的单数项,以及映射中的单数键,始终、无处不在。语言设计取决于此。Clojure 1.3 做了一些明确的非向后兼容的更改以更接近这一理想状态。
违背平等的预期行为很可能会在某个地方、以某种方式引起麻烦。当你真正需要它们时,使用你自己的类似集合的复合材料并不太困难,而不必将你的意志强加在核心平等上。
也就是说,如果您确实愿意,可以使用许多 Java 互操作函数和宏来破坏 equals 系统。请参阅http://clojure.org/datatypes作为起点。