Clojure原子不';在定义的函数中包装时不更新
不确定这里发生了什么,但我有一段代码,其中map函数在我的repl中成功执行,而没有包装在定义的函数中:Clojure原子不';在定义的函数中包装时不更新,clojure,clojurescript,Clojure,Clojurescript,不确定这里发生了什么,但我有一段代码,其中map函数在我的repl中成功执行,而没有包装在定义的函数中: (def dogs '({:name "scout" :age 5} {:name "rux" :age 3} {:name "fenley" :age 2})) (def ages (atom {:above-four '() :below-four '()})) (map #(if (> (get-in % [:age]) 4) (swap! ages
(def dogs '({:name "scout" :age 5} {:name "rux" :age 3} {:name "fenley" :age 2}))
(def ages (atom {:above-four '() :below-four '()}))
(map
#(if (> (get-in % [:age]) 4)
(swap! ages update-in [:above-four] merge %)
(swap! ages update-in [:below-four] merge %)) dogs)
@ages
=> {:above-four ({:name "scout", :age 5}), :below-four ({:name "fenley", :age 2} {:name "rux", :age 3})}
然而,当我将map函数定义为:
(def ages (atom {:above-four '() :below-four '()}))
(def dogs '({:name "scout" :age 5} {:name "rux" :age 3} {:name "fenley" :age 2}))
(defn test-dogs []
(map
#(if (> (get-in % [:age]) 4)
(swap! ages update-in [:above-four] merge %)
(swap! ages update-in [:below-four] merge %)) dogs)
@ages)
我得到以下结果:
=> {:above-four (), :below-four ()}
我很困惑,因为这个直接从Clojure文档中获取的函数工作得很好:
(def m1 (atom {:a "A" :b "B"}))
(defn update-m1 []
(swap! m1 assoc :a "Aaay")
@m1)
=> {:a "Aaay", :b "B"}
因为
测试狗
使用映射
,所以它返回一个惰性序列。惰性序列的元素直到需要时才被实现
设置的问题是,您试图使用map
运行副作用(调用swap!
;不纯净的操作),而从未实际使用map
的结果。由于您从不从map
请求结果,因此包含swap代码>从不运行
通过使用mapv
(返回非惰性向量)或doseq
(用于执行副作用):
您可以强制运行副作用
我稍微整理了一下代码。您使用的
版本中的-是不必要的;正如对进入的调用一样。我还消除了对交换的冗余调用代码>
请注意,至少在您的示例中,atom
s的使用是完全不必要的。即使您有更复杂的用例,也要确保它们的使用是合理的。可变变量在Clojure这样的语言中并不常见。准确显示了如何调用测试狗。我怀疑这是因为map
的懒惰。如果您将映射
更改为doseq
,它会修复它吗?此外,这里确实没有任何理由使用atom
s。他们只是让事情稍微复杂一点。需要使用一个原子,因为这是一个需要它的大型程序的简化示例。Doseq返回CompilerException java.lang.IllegalArgumentException:Doseq需要一个向量用于其在垃圾邮件问题中的绑定。核心:2您需要为Doseq
使用正确的语法。实际上,对于这个测试,只需将map
更改为mapv
。非常感谢!成功了。
(doseq [dog dogs]
(let [k (if (> (:age dog) 4)
:above-four
:below-four)]
(swap! ages update k merge dog)))