我需要在Clojure中全局存储一些数据的方法。但我找不到这样做的方法。我需要在运行时加载一些数据并将其放到全局对象池中,以便稍后进行操作。应该在一些函数集中访问这个池来设置/从中获取数据,就像某种类似于内存的数据库一样,具有类似哈希的语法来访问。
我知道在函数式编程中它可能是错误的模式,但我不知道存储动态对象集以在运行时访问/修改/替换它的其他方法。 java.util.HashMap是某种解决方案,但无法使用序列函数访问它,当我需要使用这种集合时,我会错过Clojure的灵活性。 Lisps语法很棒,但即使开发人员在某些地方不需要它,它仍然有点卡在纯度上。
这是我想要使用它的方式:
; Defined somewhere, in "engine.templates" namespace for example
(def collection (mutable-hash))
; Way to access it
(set! collection :template-1-id (slurp "/templates/template-1.tpl"))
(set! collection :template-2-id "template string")
; Use it somewhere
(defn render-template [template-id data]
(if (nil? (get collection template-id)) "" (do-something)))
; Work with it like with other collection
(defn find-template-by-type [type]
(take-while #(= type (:type %)) collection)]
有人可以使用这种方式来完成这样的任务吗?谢谢
答案 0 :(得分:2)
看看atoms。
你的例子可以适应这样的事情(未经测试):
; Defined somewhere, in "engine.templates" namespace for example
(def collection (atom {}))
; Way to access it
(swap! collection assoc :template-1-id (slurp "/templates/template-1.tpl"))
(swap! collection assoc :template-2-id "template string")
; Use it somewhere
(defn render-template [template-id data]
(if (nil? (get @collection template-id)) "" (do-something)))
; Work with it like with other collection
(defn find-template-by-type [type]
(take-while #(= type (:type %)) @collection)]
swap!
是如何以线程安全的方式更新atom的值。另外请注意,上面的集合的引用已经由@符号添加。这就是你获得原子中包含的值的方法。 @符号是(deref collection)
的缩写。