オブジェクト指向言語の階層オブジェクト ツリーに対応する、深くネストされたマップを 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)