让我们在Clojure中绑定 [英] Let vs. Binding in Clojure

查看:115
本文介绍了让我们在Clojure中绑定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道他们是不同的,因为一个工作,设置 * compile-path * ,一个不。



使用给定的绑定创建一个新作用域,但绑定 ...?

解决方案

let 为某个值创建一个词法作用域的不可变别名。 binding 为某些 Var 创建一个动态范围的绑定。



动态绑定意味着绑定表单中的代码以及该代码调用的任何代码

 <$ c $ 

c> user> (def ^:dynamic x 0)
#'user / x

c> binding 实际上为 Var 创建了一个动态绑定,但是 let 具有本地别名:

  user> (binding [x 1](var-get#'x))
1
user> (let [x 1](var-get#'x))
0

code> binding 可以使用限定名(因为它操作 Var s)和 let 不能:

  user> (binding [user / x 1](var-get#'x))
1
user> (let [user / x 1](var-get#'x))
;评估中止。
;;无法允许限定名称:user / x

let - 引入的绑定不可变。 绑定 - 引入的绑定是线程本地可变的:

  user& (binding [x 1](set!x 2)x)
2
user> (let [x 1](set!x 2)x)
;评估中止。
;;分配目标无效

词法与动态绑定:

  user> (defn foo [](println x))
#'user / foo
user> (binding [x 1](foo))
1
nil
user> (let [x 1](foo))
0
nil

Vars let


I understand that they're different since one works for setting *compile-path* and one doesn't. However, I need help with why they're different.

let creates a new scope with the given bindings, but binding...?

解决方案

let creates a lexically scoped immutable alias for some value. binding creates a dynamically scoped binding for some Var.

Dynamic binding means that the code inside your binding form and any code which that code calls (even if not in the local lexical scope) will see the new binding.

Given:

user> (def ^:dynamic x 0)
#'user/x

binding actually creates a dynamic binding for a Var but let only shadows the var with a local alias:

user> (binding [x 1] (var-get #'x))
1
user> (let [x 1] (var-get #'x))
0

binding can use qualified names (since it operates on Vars) and let can't:

user> (binding [user/x 1] (var-get #'x))
1
user> (let [user/x 1] (var-get #'x))
; Evaluation aborted.
;; Can't let qualified name: user/x

let-introduced bindings are not mutable. binding-introduced bindings are thread-locally mutable:

user> (binding [x 1] (set! x 2) x)
2
user> (let [x 1] (set! x 2) x)
; Evaluation aborted.
;; Invalid assignment target

Lexical vs. dynamic binding:

user> (defn foo [] (println x))
#'user/foo
user> (binding [x 1] (foo))
1
nil
user> (let [x 1] (foo))
0
nil

See also Vars, let.

这篇关于让我们在Clojure中绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆