Lassen vs. Bindung in Clojure
Frage
Ich verstehe, dass sie anders ist da ein Werk für *compile-path*
Einstellung und einer nicht. Aber ich brauche Hilfe mit, warum sie anders aus.
let
schafft einen neuen Bereich mit den gegebenen Bindungen, aber binding
...?
Lösung
schafft let
ein lexikalischen unveränderlichen alias für einen Wert. binding
schafft ein dynamisch für einige Var
scoped Bindung.
Dynamische Bindung bedeutet, dass der Code in Ihrer binding
Form und jeder Code, dass Code-Anrufe (wenn auch nicht in dem lokalen lexikalischen Gültigkeitsbereich) die neue Bindung.
Gegeben:
user> (def ^:dynamic x 0)
#'user/x
binding
tatsächlich schafft ein dynamisches für eine Var
Bindung aber let
Schatten nur die var mit einem lokalen Alias:
user> (binding [x 1] (var-get #'x))
1
user> (let [x 1] (var-get #'x))
0
binding
können qualifizierte Namen verwenden (da es auf Var
s betreibt) und let
kann nicht:
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
eingeführten Bindungen sind nicht wandelbar. binding
eingeführten Bindungen sind gewinde lokal veränderliche:
user> (binding [x 1] (set! x 2) x)
2
user> (let [x 1] (set! x 2) x)
; Evaluation aborted.
;; Invalid assignment target
Lexical vs. dynamische Bindung:
user> (defn foo [] (println x))
#'user/foo
user> (binding [x 1] (foo))
1
nil
user> (let [x 1] (foo))
0
nil
Andere Tipps
Eine weitere syntaktische Unterschied für let vs Bindung:
Für die Bindung, die alle die Anfangswerte ausgewertet werden, bevor eine von ihnen gebunden sind an die Vars. Dies unterscheidet sich von let, wo Sie den Wert eines vorherigen „Alias“ in einem nachfolgenden Definition verwenden können.
user=>(let [x 1 y (+ x 1)] (println y))
2
nil
user=>(def y 0)
user=>(binding [x 1 y (+ x 1)] (println y))
1
nil
binding
bindet Wert auf einen Namen in dem Pro-Thread globales Umfeld
Wie Sie erwähnt haben, let
schafft einen neuen Rahmen für die Einbände.