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
Clojure で参照がどのように機能するかについて何かが欠けているように感じます。何が問題なのか誰か教えてもらえますか?
編集:これは完全な「コード」へのリンクです。 https://www.refheap.com/6544630b38b33b9d25d999829 ヘッドが null ではない場合、挿入関数の 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))