我觉得我错过了一些关于使用 refs 的东西,一些没有像我想的那样发生的事情。我正在制作一个线程安全的双链表,其中列表是一个包含对头和尾的引用的哈希。列表的节点由包含前一个、下一个和值的散列表示。
(defn insert
[list elem]
(dosync
(let [head @(:head list)]
(if (nil? head)
(do (ref-set (:head list) elem)
(ref-set (:tail list) elem))
(do
(ref-set (:head list) elem)
(ref-set (:next elem) head);;fails!
(ref-set (:prev head) elem))))));;fails!
这给了我一个 StackOverflow 错误。准确地说:
StackOverflowError java.util.regex.Pattern$Curly.match
感觉就像我错过了 refs 在 Clojure 中的工作方式,任何人都可以告诉我有什么问题吗?
编辑:这是完整“代码”的链接。 https://www.refheap.com/6544630b38b33b9d25d999829 它在最后一行失败,在插入函数的 else 子句中,当头部不再为空时。
(def f (create-doubly-linked-list))
(def n (create-node 2))
(insert f n)
(def m (create-node 3))
(insert (f m);;error!
请注意,当我尝试访问列表时,或者当我在 repl 中评估f时,或者当我执行 REPL 中的最后一行时,就会出现错误。
更新:以下代码有效,但访问列表会导致问题以及打印它。
(def f (create-doubly-linked-list))
(def n (create-node 2))
(insert f n)
(insert f (create-node 5))
(insert f (create-node 1))
(def m (create-node 3))
(insert f m)
(is (= @(:value @(:tail f)) 2))
(is (= @(:value @(:head f)) 3))