我是Clojure的新手,你能不能给我解释现实场景.我的意思是,在哪里使用Ref,Var,Agent,Atom.我读过书,但是,仍然无法理解现实世界的例子.
我正在使用server.socket将数据流式传输到多个客户端,server.socket为每个客户端连接使用Threads.我目前有这样的事情:
(def clients (atom ())) ; connected clients defined globally for that namespace
(swap! clients conj a) ; adds a client (which is an atom itself as well), this is in a function that is run on the client's thread
;I want to better the process of removing a client!
(dosync (reset! clients (remove #{a} @clients))) ; removes client from list, run in a function on the client's thread
Run Code Online (Sandbox Code Playgroud)
我运行一个遍历每个客户端并抓取内容的函数,它在每个多个客户端线程上处于无限循环中,因此它同时运行:
(doseq [c @clients]
(print ((deref c) :content))
(flush))
Run Code Online (Sandbox Code Playgroud)
我在线程中使用Atoms的结论确实让程序顺利运行并允许非阻塞读取,所以我对此感到满意,除非我觉得重置全局客户端的Atom只是为了让我可以从中删除单个客户端这个名单是一个糟糕的举动.有没有更合适的方法来实现这一点使用交换!?我为clients atom选择了list,因为我在每个连接的客户端上运行doseq来获取内容并将其刷新到输出流套接字.
我有一个矢量原子,我想更新一个本身就是地图的条目.
(def vector-atom (atom []))
(swap! vector-atom conj { :id 1 :name "myname" })
Run Code Online (Sandbox Code Playgroud)
我将如何仅更新此会员?
在可变的Java领域的思维模式中,我会做这样的事情:
(defn find-by-id [id]
(first (filter (fn [entry] (= (:id entry) id))
@vector-atom)))
(defn update-entry [id new-entry]
(let [curr-entry (find-by-id id)
merged-entry (merge curr-entry new-entry)]
###set the curr-entry to merged-entry###))
Run Code Online (Sandbox Code Playgroud)