clojure.core有宏bindings和with-redefs。通过查看clojuredocs.org上的文档字符串和示例,它们似乎做了非常相似的事情。它们之间有什么区别,我应该在哪些情况下使用哪个?
clojure.core有宏bindings和with-redefs。通过查看clojuredocs.org上的文档字符串和示例,它们似乎做了非常相似的事情。它们之间有什么区别,我应该在哪些情况下使用哪个?
Clojure变量可以有线程局部绑定。 binding
使用这些绑定,而 with-redefs
实际上会更改变量的根绑定(类似于默认值)。
另一个区别是 binding
仅适用于 :dynamic
变量,而 with-redefs
适用于所有变量。
示例:
user=> (def ^:dynamic *a* 1)
#'user/*a*
user=> (binding [*a* 2] *a*)
2
user=> (with-redefs [*a* 2] *a*)
2
user=> (binding [*a* 2] (doto (Thread. (fn [] (println "*a* is " *a*))) (.start) (.join)))
*a* is 1
#<Thread Thread[Thread-2,5,]>
user=> (with-redefs [*a* 2] (doto (Thread. (fn [] (println "*a* is " *a*))) (.start) (.join)))
*a* is 2
#<Thread Thread[Thread-3,5,]>
您可以使用(未记录在案的)binding-conveyor-fn
来将线程本地绑定传递到新线程中:
user=> (binding [*a* 2] (doto (Thread. (#'clojure.core/binding-conveyor-fn (fn [] (println "*a* is " *a*)))) (.start) (.join)))
*a* is 2
#<Thread Thread[Thread-5,5,]>
with-redefs
适用于测试(你可能想要调用并替换一个函数),而 binding
在生产代码中也很有用。 - Peejawith-redefs
吗? - Erik Kaplunfuture
、send
、send-off
和 pmap
具有绑定传输的能力 - 这是否意味着不再需要 binding-conveyor-fn
? - Erik Kaplunbinding-conveyor-fn
。但是,如果您使用(Thread. ...)
创建线程,则仍然需要它。 - Miikka