Can';t使用Clojure中的set更改/建立:[some def]的根绑定

Can';t使用Clojure中的set更改/建立:[some def]的根绑定,clojure,functional-programming,lisp,clojurescript,Clojure,Functional Programming,Lisp,Clojurescript,我无法将动态var的值设置为新值 (def *pop* true) (set! *pop* false) => IllegalStateException Can't change/establish root binding of: *pop* with set clojure.lang.Var.set (Var.java:221) 此外,我还添加了^:dynamic,这也不起作用 (def ^:dynamic *pop* true) (set! *pop* false)

我无法将动态var的值设置为新值

(def *pop* true)

(set! *pop* false)

=> IllegalStateException Can't change/establish root binding of: *pop* with set  clojure.lang.Var.set (Var.java:221)

此外,我还添加了
^:dynamic
,这也不起作用

(def ^:dynamic *pop* true)

(set! *pop* false)

=> IllegalStateException Can't change/establish root binding of: *pop* with set  clojure.lang.Var.set (Var.java:221)

但另一方面,这段代码是有效的,(clojure core的var->
*反射时发出警告*


动态变量只能
设置
绑定
范围内。所以只要调用
set*pop*
上的code>将不起作用-您需要位于上面调用堆栈中某个绑定的运行时动态范围内

(def ^:dynamic *pop* true)
(binding [*pop* *pop*]  ;; defaulted to the root binding value
  (set! *pop* false)    ;; ok, because in dynamic binding scope
  (println *pop*))      ;; prints "false" (inside per-thread dynamic binding)
(println *pop*)         ;; prints "true" (root value)
注意,它的“动态范围”部分意味着在
绑定中
可以进行任意嵌套调用,并且仍然可以访问设置和读取
*pop*
的每线程值

关于
*反射警告*
,这看起来像是特殊行为,但实际上完全相同,只是隐藏在视图中。REPL本身围绕每个REPL语句的eval创建一个动态绑定范围,并为一组硬编码的动态变量进行绑定,其中
*反射时发出警告*
就是其中之一。您可以找到该绑定集。

您可以使用它来更改根变量

user=>(def*pop*true)
警告:*pop*未声明为动态。。。
#'user/*pop*
user=>(alter var root#'*pop*(持续为false))
假的
用户=>*pop*
假的
(def ^:dynamic *pop* true)
(binding [*pop* *pop*]  ;; defaulted to the root binding value
  (set! *pop* false)    ;; ok, because in dynamic binding scope
  (println *pop*))      ;; prints "false" (inside per-thread dynamic binding)
(println *pop*)         ;; prints "true" (root value)