这是我的来电者
(resolveEntity [r entity-id]
(println "resolve" entity-id)
(recursive-get r entity-id)
(cache entity-id)
)
被叫功能
(defn recursive-get [r entity-id]
(println "recursive" entity-id)
(let [e (f (merge {} (-> r :conns first d/db (d/entity entity-id))))]
(alter-var-root #'cache assoc entity-id e)
(for [[k v] e]
(if (:db/isComponent (k components))
(if (not= (class v) Long)
(map #(recursive-get r %) v)
(recursive-get r v)
)))))
被调用的函数只调用一次。如果我删除调用者中的最后一行(cache entity-id),那么每次我想要它都会重复,但我需要返回其他内容(cache entity-id)。
我测试了一个类似但更简单的代码(一个不在调用函数尾部调用的递归函数)REPL并且它工作正常,所以我不顾一切地撞到桌子上。
答案 0 :(得分:1)
你被Lazy-Bug咬了!
如果你删除了最后一行,那么函数的返回值就是(recursive-get r entity-id)
的结果,然后repl会遍历,以便它可以打印出来。打印每个值的行为会导致计算延迟集合中的每个条目。当你在那之后添加另一行时,忽略map
的结果:没有任何内容读取,并且它们永远保持在未实现的延迟状态,并且计算永远不会发生。
要解决此问题,请将其打包到dorun
:
(dorun (recursive-get r entity-id))
或者如果您需要保存结果,请改用doall
。