سؤال
أنا أفهم أنهم مختلفون منذ عمل واحد لإعداد *compile-path*
ولا واحد لا. ومع ذلك، أحتاج إلى مساعدة في سبب اختلافها.
let
يخلق نطاق جديد مع الارتباطات المعطاة، ولكن binding
...?
المحلول
let
ينشئ اسم مستعار حلو محددا متعجل من أجل بعض القيمة. binding
يخلق ملزمة مبكر ديناميكيا لبعض Var
.
ربط ديناميكي يعني أن التعليمات البرمجية داخل binding
شكل وأي رمز يسميه رمز (حتى لو لم يكن في النطاق المعجمي المحلي) سيرى الربط الجديد.
منح:
user> (def ^:dynamic x 0)
#'user/x
binding
في الواقع يخلق ملزمة ديناميكية ل Var
لكن let
فقط الظلال الفايرة مع الاسم المستعار المحلي:
user> (binding [x 1] (var-get #'x))
1
user> (let [x 1] (var-get #'x))
0
binding
يمكن استخدام أسماء مؤهلة (نظرا لأنها تعمل على Var
رمل let
لا تستطيع:
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
الارتباطات المتسلسلة ليست قابلة للتغيير. binding
الارتباطات المتسلسلة هي موضوع قابلة للتغيير محليا:
user> (binding [x 1] (set! x 2) x)
2
user> (let [x 1] (set! x 2) x)
; Evaluation aborted.
;; Invalid assignment target
معجم مقابل ملزمة ديناميكية:
user> (defn foo [] (println x))
#'user/foo
user> (binding [x 1] (foo))
1
nil
user> (let [x 1] (foo))
0
nil
نصائح أخرى
فرق آخر سلن آخر للسماح ل VS Binding:
للربط، يتم تقييم جميع القيم الأولية قبل أن يرتبط أي منها بأي منهم إلى Vars. هذا يختلف عن السماح، حيث يمكنك استخدام قيمة "الاسم المستعار" السابق في تعريف لاحق.
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
يربط قيمة إلى اسم في البيئة العالمية لكل موضوع
كما ذكرت، let
يخلق نطاق جديد للملفات المذكورة.