Clojure与闭包中的局部变量
在Clojure中,通过Clojure与闭包中的局部变量,clojure,closures,Clojure,Closures,在Clojure中,通过和局部变量定义的变量是否可以通过闭包访问 考虑以下示例: (defn foo [] (with-local-vars [bar 10] (fn [] @bar))) ((foo)) 结果如下: #object[clojure.lang.Var$Unbound 0x131f68d8 "Unbound: #<Var: --unnamed-->"] (defn foo [] (with-local-vars [bar
和局部变量定义的变量是否可以通过闭包访问
考虑以下示例:
(defn foo []
(with-local-vars [bar 10]
(fn [] @bar)))
((foo))
结果如下:
#object[clojure.lang.Var$Unbound 0x131f68d8 "Unbound: #<Var: --unnamed-->"]
(defn foo []
(with-local-vars [bar 10] @bar))
(foo)
结果:10
基于上述情况,我不清楚在Clojure中使用本地VAR是否有效,但我怀疑答案是否定的。您能否确认这一点(或者反驳,并解释我在第一个示例中的错误)?如果我的假设是明确的(即局部变量不能用于闭包),那么请解释原因是什么
编辑:对于记录,.使用本地变量的文档在这里似乎不是特别清楚。它只是说它为变量创建了线程本地绑定,但没有说明当您使用本地变量退出作用域时会发生什么
相比之下,显式地说线程本地绑定在离开该作用域时弹出
如果查看源代码,您可以看到带有本地变量的和带有绑定的都是使用相同的基本机制(pushThreadBindings
和popThreadBindings
)实现的,这表明它们应该具有几乎相同的行为
因此,是的,您是对的,您不能期望闭包中捕获的带有本地变量的值在带有本地变量的范围之外工作。但是,Clojure提供了专门用于构建此类闭包的机制,捕获所有当前线程本地绑定:
(def foo (with-local-vars [bar 10] (fn [] @bar)))
(foo)
; => #object[clojure.lang.Var$Unbound 0x60063e12 "Unbound: #<Var: --unnamed-->"]
(def baz (with-local-vars [bar 10] (bound-fn [] @bar)))
(baz)
; => 10
(def foo(带有本地变量[bar 10](fn[]@bar)))
(富)
; => #对象[clojure.lang.Var$Unbound 0x60063e12“Unbound:#”]
(def baz(带局部变量[bar 10](绑定fn[]@bar)))
(巴兹)
; => 10
感谢您的快速响应,这似乎确实是在闭包中使用局部变量的正确方法。很高兴能学到一些新的东西:)不幸的是,尽管它并没有解决我原来的问题,因为每次调用返回函数时,局部变量的值似乎都是“重置”的(有关详细信息,请参见编辑中链接的CodeReview问题)。@Attilio-我不清楚您预期的行为是什么(在你的另一个问题中)。如果你只是用logfun
定义中的替换为(let[depth(atom 0)])
呢?这会产生你想要的行为吗?如果不会,你可以尝试将let
移动到defn logfun
之外(这将允许logfun
关闭depth
,而无需对其进行全局定义)。