let
sombras la toplevel Var x
con una local x
. let
no crea un Var ni afecta el nivel de Var; enlaza algún símbolo de manera que las referencias locales a ese símbolo serán reemplazadas por el valor let
-bound. let
tiene alcance léxico, por lo que sus enlaces solo son visibles dentro del formulario let
(no en funciones llamadas desde let
).
binding
temporalmente (thread-localmente) cambia el valor de toplevel Var x
, eso es todo lo que hace. Si hay un enlace let
en su lugar, binding
no lo ve cuando se decide qué valor cambiar (y las vinculaciones let
no son variables y no son modificables, por lo que 'algo bueno o le daría un error'). Y binding
no enmascara let
. binding
tiene un alcance dinámico, por lo que sus efectos en niveles Vars son visibles dentro del formulario binding
y en cualquier función que se llame desde el formulario binding
.
acceder al valor de la llanura de edad x
le dará todo lo que es en la parte superior de la pila de fijaciones, ya sea el más anidada let
valor -bound de x
(o el parámetro de función llamada x
, o algún valor x
se sustituye si usa su propia macro u otras posibilidades.), y solo usa el valor actual de la topología Var x
de manera predeterminada si no hay otro enlace en su lugar.
Incluso si el nivel superior Var x
está enmascarado por un let
-bound x
, siempre se puede acceder al nivel superior a través de Var @#'x
. Prueba esta versión, tal vez que va a hacer más sentido:
(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 "---"))))))
Da:
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
---
Con el fin de evitar la repetición de la documentación, tal vez se podría describir lo que espera y por qué es diferente de lo que realmente sucede . –