Ich verstehe, dass sie unterschiedlich sind, da man für die Einstellung arbeitet *compile-path*und man nicht. Ich brauche jedoch Hilfe, warum sie anders sind.
leterstellt einen neuen Bereich mit den angegebenen Bindungen, aber binding...?
Antworten:
letErstellt einen unveränderlichen Alias mit lexikalischem Gültigkeitsbereich für einen bestimmten Wert. bindingerstellt für einige eine Bindung mit dynamischem Gültigkeitsbereich Var.
Dynamische Bindung bedeutet, dass der Code in Ihrem bindingFormular und jeder Code, den dieser Code aufruft (auch wenn er nicht im lokalen lexikalischen Bereich liegt), die neue Bindung sehen.
Gegeben:
user> (def ^:dynamic x 0)
#'user/x
bindingErstellt tatsächlich eine dynamische Bindung für a Var, letschattiert die Variable jedoch nur mit einem lokalen Alias:
user> (binding [x 1] (var-get #'x))
1
user> (let [x 1] (var-get #'x))
0
bindingkann qualifizierte Namen verwenden (da es mit Vars arbeitet) und letkann 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
leteingeführte Bindungen sind nicht veränderlich. bindingeingeführte Bindungen sind thread-lokal veränderbar:
user> (binding [x 1] (set! x 2) x)
2
user> (let [x 1] (set! x 2) x)
; Evaluation aborted.
;; Invalid assignment target
Lexikalische vs. dynamische Bindung:
user> (defn foo [] (println x))
#'user/foo
user> (binding [x 1] (foo))
1
nil
user> (let [x 1] (foo))
0
nil
Ein weiterer syntaktischer Unterschied zwischen let und bindung:
Für die Bindung werden alle Anfangswerte ausgewertet, bevor sie an die Variablen gebunden werden. Dies unterscheidet sich von let, wo Sie den Wert eines vorherigen "Alias" in einer 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 einen Wert an einen Namen in der globalen Umgebung pro Thread
Wie Sie bereits erwähnt haben, letwird ein neuer Bereich für diese Bindungen erstellt.