*compile-path*
을 설정하기 때문에 다른 것이므로 하나는 이해하지 못합니다. 그러나, 나는 그들이 왜 다른지에 대한 도움이 필요합니다.Clojure에서 Let vs. Binding을 작성하십시오.
let
은 지정된 바인딩을 사용하여 새 범위를 만듭니다. 그러나 binding
...?
*compile-path*
을 설정하기 때문에 다른 것이므로 하나는 이해하지 못합니다. 그러나, 나는 그들이 왜 다른지에 대한 도움이 필요합니다.Clojure에서 Let vs. Binding을 작성하십시오.
let
은 지정된 바인딩을 사용하여 새 범위를 만듭니다. 그러나 binding
...?
let
은 일부 값에 대해 어휘 적으로 범위가 지정되지 않은 변경할 수없는 별칭을 만듭니다. binding
은 Var
에 대해 동적 범위가 지정된 바인딩을 만듭니다.
동적 바인딩은 binding
양식의 코드와 해당 코드가 호출하는 모든 코드 (로컬 어휘 범위가 아닌 경우에도)가 새 바인딩을 볼 수 있음을 의미합니다.
을 감안할 때 : 그것은에서 작동하기 때문에
user> (binding [x 1] (var-get #'x))
1
user> (let [x 1] (var-get #'x))
0
binding
이 (자격을 갖춘 이름을 사용할 수 있습니다 :
user> (def ^:dynamic x 0)
#'user/x
binding
실제로 단지 로컬 별명을 가진 VAR 그림자 Var
하지만 let
바인딩 동적를 생성 Var
s) 및 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
-introduced 바인딩은 스레드 로컬로 변경할 수 있습니다 : 동적 바인딩 대
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
binding
는 스레드 별 지구 환경
당신이 언급 한 바와 같이, let
말했다 바인딩을위한 새로운 범위를 생성에 이름에 값을 바인딩합니다.
또 하나 개의 문법 차이 : 그 중 하나가 바르에 결합되기 전에 바인딩에 대한
모든 초기 값이 평가됩니다. 이것은 let과는 다른데, 여기서 후속 정의에서 이전 "별명"의 값을 사용할 수 있습니다.
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
두 번째 예제가 작동하도록하려면^: dynamic이 x를 0 (동적으로)으로 정의해야합니다. – John
이 플러스 http://en.wikipedia.org/wiki/Scope_(programming)#Static_versus_dynamic_scoping은 내 이해를 향상 시켰습니다. 감사합니다! – Carl
x는 오류가 발생하지 않도록^: 동적 힌트로 바인딩되어야합니다. – WeGi