Вы assoc
отдаете родителя ребенку, но затем выбрасываете новое Element
. Вам необходимо установить значение в атоме, используя reset!
или swap!
:
(swap! parent assoc :child child) ; Equivalent to (swap! parent #(assoc % :child child))
(swap! child assoc :parent parent)
swap!
аналогично update
, ноон заменяет значение, хранящееся в atom
.
Также обратите внимание, что вы дали полю имя children
, но в своем примере вы ссылаетесь на него, используя :child
. children
предполагает наличие нескольких детей, поэтому я бы изменил его, чтобы он начинался как вектор вместо nil
, а затем conj
. Я бы также создал new-element
помощник:
(defrecord Element [position size parent children state type value])
(defn new-element [position size]
(->Element position size nil [] :collapsed :container nil))
(def parent (atom (new-element {:x 0 :y 0} {:width 1600 :height 900})))
(def child (atom (new-element {:x 5 :y 5} {:width 100 :height 100})))
(swap! parent update :children conj child)
(swap! child assoc :parent parent)
Чтобы устранить полученную ошибку, она отлично работает для меня в Clojure .
Если я печатаю parent
и child
после запуска приведенного выше кода, я получаю бесконечный вывод, потому что для печати родительского элемента вам нужно распечатать дочерний элемент, а для печати дочернего элемента вы должны распечатать родительский ... Это все еще работает для меня.
Убедитесь, что ошибка не возникает, потому что вы пытаетесь распечатать структуру в REPL.
Это также может быть ограничением Clojurescript,К сожалению, я не могу ответить за это, так как я не знаком с Cljs.
Я удалю свой ответ, если это окажется бесполезным.
Я тожеобратите внимание, что вложение атомов не является хорошей идеей. atom
s - это действительно изменяемые контейнеры для хранения неизменяемых объектов. Может быть, чище иметь систему идентификаторов, и каждый родитель / ребенок должен иметь числовой идентификатор своего ребенка / родителя. Тогда у вас есть один атом для всей вашей программы. Атомы могут содержать карту ID-> element для удобства поиска.