Ответ 1
let
затеняет верхний уровень Var x
локальным x
. let
не создает Var или не влияет на верхний уровень Var; он связывает некоторый символ таким образом, что локальные ссылки на этот символ будут заменены значением let
-bound. let
имеет лексическую область видимости, поэтому ее привязки видны только в самой форме let
(не в функциях, вызываемых из let
).
binding
временно (thread-local) изменяет значение верхнего уровня Var x
, что все, что он делает. Если привязка let
на месте, binding
не видит ее при выборе значения для изменения (и let
привязки не являются vars и не изменяются, так что "хорошая вещь или это даст вам ошибка). И binding
не будет маскировать let
. binding
имеет динамический масштаб, поэтому его влияние на верхние уровни Vars видны в форме binding
и в любой функции, которая вызывается из формы binding
.
Доступ к значению простого старого x
даст вам все, что находится в верхней части стека привязок, либо самое вложенное let
-граничное значение x
(или функция paramater, называемая x
, или некоторое значение x
заменяется, если вы используете свой собственный макрос или другие возможности.) и по умолчанию использует только текущее значение верхнего уровня Var x
, если нет другой привязки на месте.
Даже если верхний уровень Var x
замаскирован символом let
-bound x
, вы всегда можете получить доступ к параметру Var с помощью @#'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
---