首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >重写Clojure deftype中的equals、hashCode和toString

重写Clojure deftype中的equals、hashCode和toString
EN

Stack Overflow用户
提问于 2010-06-11 04:46:13
回答 1查看 3.1K关注 0票数 11

我正在尝试使用deftype在Clojure中创建一个新类型来实现一个二维(x,y)坐标,它实现了一个“位置”协议。

我还想让它实现标准的Java equals、hashCode和toString方法。

我最初的尝试是:

代码语言:javascript
复制
 (defprotocol Location   
   (get-x [p])  
   (get-y [p])   
   (add [p q]))


 (deftype Point [#^Integer x #^Integer y]   
     Location
       (get-x [p] x)
       (get-y [p] y) 
       (add [p q] 
         (let [x2 (get-x q)
               y2 (get-y q)]
           (Point. (+ x x2) (+ y y2))))   
     Object
       (toString [self] (str "(" x "," y ")"))
       (hashCode [self] (unchecked-add x (Integer/rotateRight y 16)))
       (equals [self b] 
         (and 
           (XXXinstanceofXXX Location b) 
           (= x (get-x b)) 
           (= y (get-y b)))))

但是,equals方法仍然需要一些方法来确定b参数是否实现了Location协议。

什么是正确的方法?我在正确的轨道上吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2010-06-11 05:23:21

要测试某些东西是否满足协议,可以使用satisfies?

编辑:

协议和数据类型在Clojure中太新了(而且还在快速发展),我不知道什么是惯用的,什么不是。但是您应该注意到,defrecord已经实现了基于类型和值的相等。除非您确实需要对象的自定义哈希码,否则可以考虑使用defrecord

代码语言:javascript
复制
(defrecord Point [#^Integer x #^Integer y]   
  Location
  (get-x [p] x)
  (get-y [p] y) 
  (add [p q] 
       (let [x2 (get-x q)
             y2 (get-y q)]
         (Point. (+ x x2) (+ y y2)))))

user> (= (Point. 1 2) {:x 1 :y 2})
false
user> (= (Point. 1 2) (Point. 1 2))
true

您还可以获得额外的好处,即能够通过关键字查找访问您的字段,并能够将元数据放到您的对象上,这是defrecord免费提供给您的。

代码语言:javascript
复制
user> (:x (Point. 1 2))
1

将来有一天,defrecord-defined中的东西可能会有自定义的阅读器语法,这样它们就可以用Clojure阅读器以可读的方式打印出来并读回。除非您真的依赖于您的toString版本,否则您可能也要牢记这一点。现在,记录已经打印出来,即使不是机器可读的,也是人类可读的。

代码语言:javascript
复制
user> (Point. 1 2)
#:user.Point{:x 1, :y 2}
票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3018372

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档