因此,我已经对此进行了测试,据我所知,这一切都可以正常工作。
在下面的示例中,我创建了一个 var,然后将此 var 重新绑定到一个函数。正如你所看到的,对函数的调用发生在绑定形式的词法范围之外,所以我们在这里有动态绑定。
(def
^{:dynamic true}
*bnd-fn*
nil
)
(defn fn1 []
(println "fn1"))
(defn fn2 []
(println "fn2"))
(defn callfn []
(*bnd-fn*))
;; crash with NPE
(callfn)
;; prints fn1
(binding [*bnd-fn* fn1]
(callfn))
;; prints fn2
(binding [*bnd-fn* fn2]
(callfn))
我一直在为我自己的库使用类似的方法(如果您有兴趣,请使用 Clojure-owl!),尽管在我的情况下,我动态重新绑定的东西是 Java 对象。
在这种情况下,虽然我允许动态重新绑定,但在大多数情况下我不允许;我只是为不同的名称空间使用不同的 java 对象。这对我很有效。
在回复您的评论时,如果您想拥有一个单一的绑定表单,那么这很容易实现。添加以下代码。
(defn dobinding [fn]
(binding [*bnd-fn* fn]
(callfn)))
(dorun
(map dobinding
[fn1 fn2]))
函数 dobinding 运行所有其他函数。然后我用一张地图评估这个(和 dorun 或者你得到一个惰性序列)。这为每个步骤运行两个函数。显然,您需要传入一个列表列表。如果您愿意,您应该能够并行化整个批次。
这比尝试拼接整个向量要容易得多。绑定表单中的值被评估,因此它可以是您喜欢的任何值。