Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
^:dynamic在Clojure中做什么?_Clojure - Fatal编程技术网

^:dynamic在Clojure中做什么?

^:dynamic在Clojure中做什么?,clojure,Clojure,我在谷歌上搜索了“clojure dynamic”和“clojure dynamic scope”,阅读了10多篇文章,但我仍然不清楚^:dyanmic的功能,但是代码示例似乎“缺失”,所以我甚至不确定它是否指的是我所困惑的同一件事 我试图解决项目中的一个问题,但首先我必须理解代码。其功能定义如下: (defn ^:dynamic parse-html "Resolve and apply crouton's HTML parsing." [& args] {:pre [cr

我在谷歌上搜索了“clojure dynamic”和“clojure dynamic scope”,阅读了10多篇文章,但我仍然不清楚
^:dyanmic
的功能,但是代码示例似乎“缺失”,所以我甚至不确定它是否指的是我所困惑的同一件事

我试图解决项目中的一个问题,但首先我必须理解代码。其功能定义如下:

(defn ^:dynamic parse-html
  "Resolve and apply crouton's HTML parsing."
  [& args]
  {:pre [crouton-enabled?]}
  (apply (ns-resolve (symbol "crouton.html") (symbol "parse")) args))

但我不明白那是什么意思。有人能用一种非常简单的方式向我解释一下吗

它将函数定义为动态范围

换句话说,这允许某人在给定函数调用中重新绑定
解析html
,并使新绑定仅应用于从该特定调用调用的函数


如果
parse html
没有动态限定范围,那么重新绑定将导致任何使用
parse html
的代码看到新绑定,而不仅仅是通过执行重新绑定的函数调用激活的代码

动态作用域作为全局作用域变量的替代品很有用。一个函数可以说“让current\u numeric\u base=16;调用其他函数”;其他函数都将以十六进制打印。然后,当它们返回,并且base设置函数返回时,base将返回到原来的状态。


正如在下面的评论中指出的,您实际上不能重新绑定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))
(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. 一,

词汇范围变量的示例:

(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))
(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

很酷,这是一个非常好的答案,但如果您使用^:dynamic向我展示一些示例代码,并演示您所解释的差异,我会觉得我会更好地理解它。您介意这样做吗?如果
parse html
没有动态范围,那么重新绑定它将是非法的。