(def ^:dynamic *d* 1)
(binding [*d* 2]
(println *d*)
(repeatedly 1 #(println *d*)))
输出:
2
1
为什么呢?为什么repeatedly
内的函数会在binding
之外看到动态变量的值?
顺便说一句,我检查了匿名函数内外的(.getId (java.lang.Thread/currentThread))
:它是一样的。
答案 0 :(得分:9)
由repeatedly
创建的延迟序列从表单返回,然后只有在通过REPL打印后才能实现,在绑定被“解开”之后,此时匿名函数正在进行调用。要看到这种情况,请尝试以下两种变体:
(binding [*d* 2]
(println *d*)
(let [x (repeatedly 1 #(println *d*))]
(println (realized? x))
x))
和
(binding [*d* 2]
(println *d*)
(doall (repeatedly 1 #(println *d*))))
第二种变化迫使序列完全实现,同时仍然在绑定范围内。
请注意,另一种强制解决问题的方法是使用bound-fn
“捕获”绑定:
(binding [*d* 2]
(println *d*)
(repeatedly 1 (bound-fn [] (println *d*))))