let
阴影顶层瓦尔x
用当地x
。 let
不会创建Var或影响顶层Var;它会绑定一些符号,以便将该符号的本地引用替换为绑定值let
。 let
具有词汇范围,因此其绑定仅在let
表单本身中可见(不在let
内调用的函数中)。
binding
临时(线程本地)更改顶级Var x
的值,就是这么做。如果有一个let
绑定,binding
在决定要更改哪个值时看不到它(并且let
的绑定不是变量,也不可更改,所以这是一件好事或它会给你一个错误)。并且binding
不会掩盖let
。 binding
具有动态范围,因此其对顶级变量的影响在binding
表单以及从binding
表单内调用的任何函数中都可见。
访问的老式x
值会给你什么是绑定的堆栈的顶部,任x
最嵌套let
结合的值(或功能paramater称为x
,或一些价值x
被替换如果您使用自己的宏或其他可能性),并且如果没有其他绑定,则仅默认使用顶级变量Var x
的当前值。
即使顶层瓦尔x
由let
结合的x
掩盖,你可以随时通过@#'x
访问顶层无功。试试这个版本,也许会更有意义:
(def x 1)
(defn dummy-fn2[]
(println "x from dummy-fn2:" x)
(+ x 1))
(defn dummy-fn[]
(println "entering function:" x)
(println "var x:" @#'x)
(dummy-fn2)
(println "---")
(let [x 100]
(println "after let:" x)
(println "var x:" @#'x)
(dummy-fn2)
(println "---")
(let [x (dummy-fn2)]
(println "after let and dummy-fn2:" x)
(println "var x:" @#'x)
(dummy-fn2)
(println "---")
(binding [x 888]
(println "after binding:" x)
(println "var x:" @#'x)
(dummy-fn2)
(println "---")
(let [x (dummy-fn2)]
(println "after binding and dummy2:" x)
(println "var x:" @#'x)
(dummy-fn2)
(println "---"))))))
给出:
entering function: 1
var x: 1
x from dummy-fn2: 1
---
after let: 100
var x: 1
x from dummy-fn2: 1
---
x from dummy-fn2: 1
after let and dummy-fn2: 2
var x: 1
x from dummy-fn2: 1
---
after binding: 2
var x: 888
x from dummy-fn2: 888
---
x from dummy-fn2: 888
after binding and dummy2: 889
var x: 888
x from dummy-fn2: 888
---
为了避免重复的文件,或许你可以描述你期望什么,以及为什么它是从实际发生的情况不同。 – 2009-11-21 03:39:59