假设我们正在使用面向对象的语言,并且有两个类X和Y,并且这些类之间存在双向关系. 因此,X的实例可以指向Y的实例,反之亦然. 在Clojure中,类通常会转换为地图,因此我们可以: {:type :x :
因此,X的实例可以指向Y的实例,反之亦然.
在Clojure中,类通常会转换为地图,因此我们可以:
{:type :x :name "instance of X"} {:type :y :name "instance of Y"}
我们如何在不使用“外键”之类的东西的情况下表示这些“对象”之间的双向关系?或者这通常是直接委托给数据库的东西?
在Clojure中看到深层嵌套的地图很常见,这些地图对应于面向对象语言中的分层对象树,例如,{:type :x :name "instance of X" :y {:type :y :name "instance of Y"}}
事实上,这是如此常见,以至于clojure.core提供了诸如get-in,assoc-in和update-in之类的核心功能,以便于使用这些结构.
当然,当建模对象之间存在自然的层次结构或所有权关系时,这种方法效果最好.在循环引用的情况下,这种结构会崩溃(假设您坚持使用持久性数据结构) – 要了解原因,请尝试构建一个将自身包含为值的Clojure映射.
我通常看到的方法是使用atom引入一个间接层:
(def x {:type :x, :name "x instance", :y (atom nil)}) (def y {:type :y, :name "y instance", :x (atom nil)}) (set! *print-level* 3) ;; do this in the REPL to avoid stack overflow ;; when printing the results of the following calls (reset! (:y x) y) (reset! (:x y) x)