有几篇有些旧的博客文章建议在混合动态变量时要小心,binding
, 和 pmap
,例如here ,我们得到以下代码片段:
user=> (def *foo* 5)
#'user/*foo*
user=> (defn adder
[param]
(+ *foo* param))
#'user/adder
user=> (binding [*foo* 10]
(doseq [v (pmap adder (repeat 3 5))]
(println v)))
10
10
10
nil
但这不是我运行该代码时发生的情况(将第一行更改为
(def ^:dynamic *foo* 5)
)。我得到三个 15
s 作为输出(使用 Clojure 1.4),正如您天真地期望的那样,即传递给 pmap 的函数看到的绑定(bind)形式的变化。线程本地绑定(bind)和 pmap 交互的方式是否发生了变化?我在任何地方都找不到这个记录。
最佳答案
从 1.3 开始,本地绑定(bind)集与函数一起发送到 pmap。因此,只要您标记 var ^:dynamic 这不再是问题。此功能称为 Binding Conveyance,包含在 1.3 变更日志中:
来自:https://github.com/clojure/clojure/blob/1.3.x/changes.txt
将工作传递给其他线程(例如 send、send-off、pmap、future)的 Clojure API 现在传达调用线程的动态绑定(bind):
(def ^:dynamic *num* 1)
(绑定(bind) [*num* 2] (future (println *num*)))
;;打印“2”,而不是“1”
关于绑定(bind)和pmap交互变化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12116878/