我有一些看起来像这样的clojure代码: (defn rect [x y w h] {:x x, :y y, :w w, :h h})(def left :x)(def top :y)(def width :w)(def height :h)(defn right [r] (+ (left r) (width r)))(defn bottom [r] (+ (top r) (height r))) 现在,以下
(defn rect [x y w h] {:x x, :y y, :w w, :h h}) (def left :x) (def top :y) (def width :w) (def height :h) (defn right [r] (+ (left r) (width r))) (defn bottom [r] (+ (top r) (height r)))
现在,以下代码似乎有点不常见:
(def left :x)
但是,我不知道任何其他方式来获得封装.
假设,我后来想以不同的方式表示我的矩形.
然后依赖(:x rect)不是一个好主意,因为:x只适用于hashmap和记录,因此我会在api中泄漏实现细节,至少在OO语言中被认为是不好的做法.
现在,如果我决定在java中实现我的rect,它会变得更糟,因为那时我必须编写包装器,如:
(defn left [rect] (.getLeft rect))
确保界面不会改变.
clojure如何解决这个问题?
您可以使用协议.首先是Clojure记录:
(defprotocol Rectangular (left [this]) (right [this])) (defrecord Rect [x y w h] Rectangular (left [this] x) (right [this] (+ x w))) (def my-rect (Rect. 1 2 3 4)) (right my-rect) ;=> 4
现在是一个Java对象:
(import java.awt.Rectangle) (extend-type Rectangle Rectangular (left [this] (int (.getX this))) (right [this] (int (+ (.getX this) (.getWidth this))))) (def my-other-rect (Rectangle. 1 2 3 4)) (right my-other-rect) ;=> 4