两个clojure映射引用互为元素
我在REF中有两个映射,希望在一个事务中将它们彼此关联 我的函数如下所示:两个clojure映射引用互为元素,clojure,circular-reference,refs,Clojure,Circular Reference,Refs,我在REF中有两个映射,希望在一个事务中将它们彼此关联 我的函数如下所示: (defn assoc-two [one two] (let [newone (assoc @one :two two) newtwo (assoc @two :one one)] (ref-set one newone) (ref-set two newtwo))) (dosync (assoc-two (ref {}) (ref {}))) 现在我像这样呼叫assoctwo
(defn assoc-two
[one two]
(let [newone (assoc @one :two two)
newtwo (assoc @two :one one)]
(ref-set one newone)
(ref-set two newtwo)))
(dosync (assoc-two (ref {}) (ref {})))
现在我像这样呼叫assoctwo
:
(defn assoc-two
[one two]
(let [newone (assoc @one :two two)
newtwo (assoc @two :one one)]
(ref-set one newone)
(ref-set two newtwo)))
(dosync (assoc-two (ref {}) (ref {})))
在这一点上,我得到了和StackOverflower错误
我也试过:
(defn alter-two
[one two]
(alter one assoc :two two)
(alter two assoc :one one))
是否可以这样做,即
one
有一个引用two的条目,反之亦然,并且仍然在一个事务中?堆栈溢出不会发生,直到您尝试打印其中一个循环引用,例如在REPL处
so.core=> (def a (ref {}))
#'so.core/a
so.core=> (def b (ref {}))
#'so.core/b
so.core=> (do (dosync (alter-two a b)) :success)
:success
so.core=> (= b (:two @a))
true
so.core=> (= a (:one @b))
true
so.core=>(defa(ref{}))
#“那么,core/a
so.core=>(def b(ref{}))
#'so.core/b
so.core=>(do(dosync(altertwoab)):success)
:成功
so.core=>(=b(:two@a))
真的
so.core=>(=a(:one@b))
真的
显然,像这样打印循环引用的对象会有问题,但请参阅关于禁用引用类型内容的默认打印
(remove-method print-method clojure.lang.IDeref)
(dosync (alter-two (ref {}) (ref {})))
;=> {:one #<Ref clojure.lang.Ref@7f1f91ac>}
; (prints the second ref without attempting to print its circular contents)
(删除方法打印方法clojure.lang.IDeref)
(dosync(altertwo(ref{})(ref{})))
;=> {:一#}
; (打印第二个ref,而不尝试打印其循环内容)
答案可以在下面的几篇文章中找到,这只是试图打印递归结构的REPL。
您必须删除打印方法:
(remove-method print-method clojure.lang.IDeref)
或者添加一个print方法来处理您的特定案例,这个方法必须比常见的clojure.lang.IDeref
更具体。哦,我可能已经猜到了。非常感谢。