它将函数定义为动态范围。
换句话说,这允许某人parse-html
在给定的函数调用中重新绑定,并使该新绑定仅适用于从该特定调用调用的函数。
如果parse-html
不是动态范围的,那么重新绑定将导致新绑定被任何使用的代码看到,parse-html
而不仅仅是由执行重新绑定的函数调用激活的代码。
动态范围可用于替代全局范围的变量。一个函数可以说“让 current_numeric_base = 16;调用其他函数;” 其他函数都将以十六进制打印。然后当它们返回时,基数设置函数返回,基数将返回到原来的状态。
http://c2.com/cgi/wiki?DynamicScoping
正如下面评论中所指出的,您实际上不能重新绑定在 Clojure 中没有动态作用域的变量。如果可以的话,更新一个词法范围的变量将影响所有执行的代码,即使它运行在与重新绑定发生位置不同的调用堆栈中。
所以也许一些伪代码会使动态范围和词法范围之间的区别变得清晰。
使用动态范围变量的示例:
(def ^:dynamic a 0)
(defn some-func [x] (+ x 1))
; re-binds a to 1 for everything in the callstack from the (binding)
; call and down
(binding [a 1]
(print (some-func a)))
; a was only re-bound for anything that was called from
; within binding (above) so at this point a is bound to 0.
(print (some-func a))
将打印:
2 1
词法范围变量的示例:
(def a 0)
(defn some-func [x] (+ x 1))
; re-binds a to 1 for everyone, not just things that
; are in the callstack created at this line
(set-var [a 1] ; set-var is a made up function that can re-bind lexically scoped variables
(print (some-func a)))
; a was lexically scoped so changing it changed
; it globally and not just for the callstack that
; contained the set-var.
(print (some-func a))
将打印:
2 2