문제

설정을 위해 일하기 때문에 그들이 다르다는 것을 이해합니다. *compile-path* 그리고 하나는 아닙니다. 그러나 왜 다른지에 대한 도움이 필요합니다.

let 주어진 바인딩으로 새로운 범위를 만들지 만 binding...?

도움이 되었습니까?

해결책

let 일부 가치에 대해 어휘 스코프 링 불변의 별칭을 만듭니다. binding 일부는 동적으로 스코핑 된 바인딩을 만듭니다 Var.

동적 바인딩은 내부의 코드를 의미합니다 binding 양식 및 해당 코드가 호출되는 모든 코드 (로컬 어휘 범위가 아닌 경우에도)는 새로운 바인딩을 볼 수 있습니다.

주어진:

user> (def ^:dynamic x 0)
#'user/x

binding 실제로 a에 대한 동적 바인딩을 만듭니다 Var 하지만 let 로컬 별칭으로 VAR을 그림자로 만 묘사합니다.

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

또한보십시오 vars, 허락하다.

다른 팁

LET 대 바인딩에 대한 하나의 구문 차이 :

바인딩의 경우, 모든 초기 값은 VARS에 묶여 있기 전에 평가됩니다. 이것은 후속 정의에서 이전 "별칭"의 값을 사용할 수있는 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

binding 스레드 당 글로벌 환경에서 값을 이름에 바인딩합니다.

당신이 언급했듯이 let 상기 바인딩에 대한 새로운 범위를 만듭니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top