评论由:troydm 提出
我认为问题与以下代码段有关
`
(defn walk* [s v]
(let [v (walk s v)]
(walk-term v
(fn [x]
(let [x (walk s x)]
(if (tree-term? x)
(walk* s x)
x))))))
`
另一方面则调用
`
clojure.lang.IPersistentVector
(walk-term [v f])
(with-meta
(loop [v v r (transient [])]
(if (seq v)
(recur (next v) (conj! r (walk-term (f (first v)) f)))
(persistent! r)))
(meta v)))
`
这会递归地为向量的所有元素调用 walk-term。
然后为向量的每个元素调用 walk-term,这反过来又会调用 walk* 过去访问过的向量元素。
结果导致多次回到子节点。
整体结果是将子节点多次访问。
问题是 walk 函数部分递归地调用 walk 为 walk-term 函数调用的先前遍历的向量元素。
`
(if (tree-term? x)
(walk* s x)
x)
`
我认为这部分的整体设计有很大的问题,我不确定在这里可以提出什么建议,但我认为我们需要将 walk-term 和 walk* 合并成一个函数,一次性遍历整个数据结构,有什么建议吗?
可能的解决方案如下代码,但我不确定它是否正确
`
(defn walk* [s v]
(let [v (walk s v)]
(walk-term v
#(walk s %))))
`