Ert*_*tin 6 lisp functional-programming clojure 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)
Run Code Online (Sandbox Code Playgroud)
我也补充说^: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)
Run Code Online (Sandbox Code Playgroud)
但另一方面,这段代码有效,(clojure core的var - > *warn-on-reflection*)
(set! *warn-on-reflection* true)
=> true
*warn-on-reflection*
=> true
(set! *warn-on-reflection* false)
=> false
*warn-on-reflection*
=> false
Run Code Online (Sandbox Code Playgroud)
动态变量只能set!在binding范围内.所以只要调用set!上*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)
Run Code Online (Sandbox Code Playgroud)
请注意,它的"动态范围"部分意味着binding您可以在其中进行任意嵌套调用,并且仍然可以访问设置和读取每个线程的值*pop*.
关于*warn-on-reflection*,这看起来像特殊行为,但它实际上完全相同,除了从视图中隐藏.REPL本身围绕每个REPL语句的eval创建一个动态绑定范围,其中绑定了一组硬编码的动态变量,其中*warn-on-reflection*一个是动态变量.你可以在这里找到那组绑定.
您可以使用alter-var-root更改根变量。
user=> (def *pop* true)
Warning: *pop* not declared dynamic ...
#'user/*pop*
user=> (alter-var-root #'*pop* (constantly false))
false
user=> *pop*
false
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1274 次 |
| 最近记录: |