在混合动态变量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
作为输出(使用Clojure 1.4),就像你天真期望的那样 - 也就是说,传递给pmap的函数看到的绑定形式的变化。线程局部绑定和pmap交互的方式有变化吗?我无法在任何地方找到这些文件。
答案 0 :(得分:5)
从1.3开始,本地绑定集与函数一起发送到pmap。所以只要你标记var ^:dynamic就不再是问题了。此功能称为绑定传送,并包含在1.3更改日志中:
来自:https://github.com/clojure/clojure/blob/1.3.x/changes.txt
Clojure APIs that pass work off to other threads (e.g. send, send-off, pmap, future) now convey the dynamic bindings of the calling thread: (def ^:dynamic *num* 1) (binding [*num* 2] (future (println *num*))) ;; prints "2", not "1"