Clojure:将符号重新绑定到新的数据结构

时间:2013-05-31 03:15:46

标签: binding clojure symbols

如何在Clojure中将符号重新绑定到新数据结构。例如:

 (def hash-map-one {:a "foo" :b "bar"})
 (def hash-map-two {:c "gaz" :d "waka"})

 ;; right here make hash-map-one equal to hash-map-two very quickly
 ;; if this were python I would say hash-map-one = hash-map-two

有点动机,我这样做是因为我有一个依赖于数据文件的Web服务,并且该数据文件将被更新,此时我需要在不停机的情况下“切换”到新的数据

提前致谢!

1 个答案:

答案 0 :(得分:5)

根据您的使用案例,使用原子可能最有意义:

(def data (atom {:map 'of :initial "data"}))

(reset! data {:map 'of :new "data"})

如果由于某种原因您更喜欢使用Var,则可以使用alter-var-root切换到新值。你也可以使用intern,但是你失去了alter-var-root的原子性保证(请参阅docstring和this answer;评论re:def同样适用于intern {1}})。

在REPL中,使用def来重新绑定现有Vars是完全没问题,但是在生产代码中通常不是一个好主意(在Clojure实现中发现了一些值得注意的例外 - 一个非常特殊的情况)。最重要的是,def只能在顶级表单中使用,它们会立即执行它;也就是说,它应该是顶级表单本身,或者是let等顶级表单正文的一部分。否则weirdness ensues