Programing

Clojure의 Let 대 바인딩

crosscheck 2020. 11. 8. 09:19
반응형

Clojure의 Let 대 바인딩


하나는 설정을 위해 작동 *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

bindingVars에서 작동하므로 정규화 된 이름을 사용할 수 있으며 다음을 수행 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을 참조하십시오 .


let과 binding에 대한 또 다른 구문 차이 :

바인딩의 경우 모든 초기 값이 변수에 바인딩되기 전에 평가됩니다. 이는 후속 정의에서 이전 "별칭"의 값을 사용할 수있는 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바인딩에 대한 새 범위를 만듭니다.

참고 URL : https://stackoverflow.com/questions/1523240/let-vs-binding-in-clojure

반응형