Clojure值相等与集合
如果我有一个自定义类型,并使用它创建两个具有完全相同值的独立实例,那么我可以使用什么方法来确定这两个对象是等效的<代码>相同?和Clojure值相等与集合,clojure,set,Clojure,Set,如果我有一个自定义类型,并使用它创建两个具有完全相同值的独立实例,那么我可以使用什么方法来确定这两个对象是等效的相同?和=和=似乎不起作用。我本以为会有一些设置类型比较的协议。归根结底,我希望这样做,就不可能在一个集合中添加相同的东西 (deftype Ref [id]) (def r1 (->Ref 1)) (def r2 (->Ref 1)) (= r1 r2) ;false rather than true (def refs #{}) (conj refs r1 r2) ;a
=
和=
似乎不起作用。我本以为会有一些设置类型比较的协议。归根结底,我希望这样做,就不可能在一个集合中添加相同的东西
(deftype Ref [id])
(def r1 (->Ref 1))
(def r2 (->Ref 1))
(= r1 r2) ;false rather than true
(def refs #{})
(conj refs r1 r2) ;adds both, but want one
=
与defrecord
一起工作,但是我如何定义=
的=
定义deftype
?defrecord
已经有了您描述的行为:
user=> (defrecord Point [x y])
user.Point
user=> (= (Point. 0 0) (Point. 0 0))
true
user=> (into #{} [(Point. 0 0) (Point. 1 1) (Point. 0 0)])
#{#user.Point{:x 1, :y 1} #user.Point{:x 0, :y 0}}
另一方面,deftype
默认情况下不实现Clojure通常的结构相等(也不实现deftstruct
提供的可读打印方法):
在deftype中,扩展
对象
并实现等于
,以赋予它们相等语义:
(deftype Ref [id]
Object
(equals [_ other] (= id (.id other))))
集合包含还需要哈希代码支持:
(deftype Ref [id]
Object
(equals [_ other] (= id (.id other)))
(hashCode [_] id)
clojure.lang.IHashEq
(hasheq [_] id))
我在那里实现了Java哈希支持和Clojure支持。实现IHashEq会更快。对于
散列集
,equals是不够的(我试过了),散列码
也是需要的。一件小事:==
只为数值数据用户>定义(==:a:a)=>ClassCastException clojure.lang.Keyword不能转换为java.lang.Number clojure.lang.Numbers.equal)(Numbers.java:206)
(deftype Ref [id]
Object
(equals [_ other] (= id (.id other))))
(deftype Ref [id]
Object
(equals [_ other] (= id (.id other)))
(hashCode [_] id)
clojure.lang.IHashEq
(hasheq [_] id))