我正在Clojure中更新地图参考中的计数器。
(defn increment-key [this key]
(dosync
(let [value (get @this key)]
(if (= value nil)
(alter this assoc key (ref 1))
(alter this assoc key (alter value inc))))))
但是,看起来alter value inc语句正在丢失引用:
(defn -main [& args]
(def my-map (ref {}))
(increment-key my-map "yellow")
(println my-map)
(increment-key my-map "yellow")
(println my-map))
打印哪些:
$ lein run
#<Ref@65dcc2a3: {yellow #<Ref@3e0d1329: 1>}>
#<Ref@65dcc2a3: {yellow 2}>
在这种情况下,如何在更新时保留相同的引用?
答案 0 :(得分:3)
你快到了。下面是解决方案,检查increment-key
的最后一行,你只需要改变值(不要改变你正在做的地图中的键,因为这导致使用alter return value更新键在你的例子中是2,记得alter返回ref的新值,而不是ref本身)。也不要在def中使用def,你应该使用let(在你的-main函数中)
(defn increment-key [this key]
(dosync
(let [value (get @this key)]
(if (= value nil)
(alter this assoc key (ref 1))
(alter value inc)))))
(defn -main [& args]
(let [my-map (ref {})]
(increment-key my-map "yellow")
(println my-map)
(increment-key my-map "yellow")
(println my-map)))