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的常用结构相等(也不是defstruct
为我们提供了可读取的打印方法):
user=> (deftype Pair [a b])
user.Pair
user=> (= (Pair. 0 0) (Pair. 0 0))
false
user=> (into #{} [(Pair. 0 0) (Pair. 1 1) (Pair. 0 0)])
#{#<Pair [email protected]> #<Pair [email protected]> #<Pair [email protected]>}
也就是说,deftype
功能更强大,您可以使其表现得像我们喜欢的:
user=> (deftype Tuple [a b]
Object
(equals [this other]
(and (= (.a this) (.a other))
(= (.b this) (.b other))))
(toString [this]
(str "<" (.a this) "," (.b this) ">"))
(hashCode [this]
(hash {:a (.a this) :b (.b this)}))
Comparable
(compareTo [this that]
(compare [(.a this) (.b this)]
[(.a that) (.b that)])))
user.Tuple
user=> (= (Tuple. 0 0) (Tuple. 0 0))
true
user=> (into #{} [(Tuple. 0 0) (Tuple. 1 1) (Tuple. 0 0)])
#{#<Tuple <0,0>> #<Tuple <1,1>>}
一件小事:'=='仅为数字数据定义'user>(==:a:a)=> ClassCastException clojure.lang.Keyword不能转换为java.lang.Number clojure.lang.Numbers .equiv(Numbers.java:206)' – noisesmith 2014-10-29 04:45:55