Let vs. Binding in Clojure
Rozumiem, że są różne, ponieważ jeden pracuje dla ustawienia *compile-path*
, a drugi nie. jednak potrzebuję pomocy, dlaczego są różne.
let
tworzy nowy zakres z podanymi wiązaniami, ale binding
...?
3 answers
let
tworzy niezmienny alias o zasięgu leksykalnym dla pewnej wartości. binding
tworzy dynamicznie skalowane Wiązanie dla niektórych Var
.
Dynamiczne Wiązanie oznacza, że kod wewnątrz formularza binding
i każdy kod, który ten kod wywoła (nawet jeśli nie znajduje się w lokalnym zakresie leksykalnym), zobaczy nowe Wiązanie.
Podane:
user> (def ^:dynamic x 0)
#'user/x
binding
w rzeczywistości tworzy dynamiczne powiązanie dla Var
, ale let
tylko cieniuje var z lokalnym aliasem:
user> (binding [x 1] (var-get #'x))
1
user> (let [x 1] (var-get #'x))
0
binding
może korzystać z kwalifikowanych nazwy (ponieważ działa na Var
s) I let
nie mogą:
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
-wprowadzone wiązania nie są zmienne. binding
- wprowadzone wiązania są mutowalne lokalnie:
user> (binding [x 1] (set! x 2) x)
2
user> (let [x 1] (set! x 2) x)
; Evaluation aborted.
;; Invalid assignment target
Wiązanie leksykalne vs. dynamiczne:
user> (defn foo [] (println x))
#'user/foo
user> (binding [x 1] (foo))
1
nil
user> (let [x 1] (foo))
0
nil
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-14 14:31:43
Jeszcze jedna różnica składniowa dla let vs binding:
W przypadku wiązania, wszystkie wartości początkowe są obliczane, zanim któreś z nich zostanie powiązane z var. Różni się to od let, gdzie można użyć wartości poprzedniego "aliasu" w późniejszej definicji.
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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-21 02:53:01
binding
wiąże wartość z nazwą w globalnym środowisku per-thread
Jak już wspomniałeś, let
tworzy nowy zakres dla wspomnianych wiązań.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-06 02:16:03