gpt4 book ai didi

Clojure - 重置!原子导致堆栈溢出

转载 作者:行者123 更新时间:2023-12-02 18:34:17 25 4
gpt4 key购买 nike

我正在学习 clojure,只是在玩原子和引用。这是一个简单的树实现,但在执行 add-child 方法时会导致堆栈溢出:

(ns mytree)

(defprotocol PNode
(add-child [this parent] "add 'this' node to the parent"))

(defrecord Node [id parent name children]
PNode
(add-child [this p]
(println "adding this to children of parent")
(dosync
(alter (:children p) conj this))

;following causes a stack overflow -why?
; (println "reseting parent of this")
; (reset! parent p)

))

(defn create-node [id name]
(Node. id (atom nil) name (ref ())))

这是来自 REPL 的示例 session :

>mytree> (def root (create-node 1 "CEO"))
>#'mytree/root
>mytree> (def child (create-node 2 "VP1"))
>#'mytree/child
>mytree> (add-child child root)

>adding this to children of parent

>(#:mytree.Node{:id 2, :parent #<Atom@4dffa9d: nil>, :name "VP1", :children #<Ref@cbe5beb: ()>})

>mytree> root
>#:mytree.Node{:id 1, :parent #<Atom@44896098: nil>, :name "CEO", :children #<Ref@2a75733a: >(#:mytree.Node{:id 2, :parent #<Atom@4dffa9d: nil>, :name "VP1", :children #<Ref@cbe5beb: ()>})>}
>mytree> (def child2 (create-node 3 "VP2"))
>#'mytree/child2

resetting parent to child2 works
>mytree> (reset! (:parent child) child2)
>#:mytree.Node{:id 3, :parent #<Atom@43c32b82: nil>, :name "VP2", :children #<Ref@425d868f: ()>}

but resetting parent to root causes stack overflow - why??
>mytree> (reset! (:parent child) root)
>; Evaluation aborted.

正如您在上面所看到的,将子进程的父进程重置为 child2 是可行的,但将其重置为根进程会导致堆栈溢出。你能帮我理解为什么吗?

最佳答案

这实际上并不是重置!,而是 REPL 尝试打印(无限)嵌套值。

试试这个:

(set! *print-level* 10)

这将限制分层对象的递归打印。

关于Clojure - 重置!原子导致堆栈溢出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5751094/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com