所以,我刚开始学习Clojure,现在我遇到了一个我不能自己谷歌的问题。
这是我的代码atm:
=> (def a "asd")
=> a
"asd"
=> (defn bla [entry_value] (def entry_value "qwe"))
=> (bla a)
#'exercise.core/entry_value
=> a
"asd"
=> entry_value
"qwe"
我真正想要的是 a 将“qwe”作为值。 有可能吗?
感谢您的帮助!
答案 0 :(得分:2)
是的,技术上可以借助alter-var-root这样的功能
=> (defn bla [entry-value] (alter-var-root entry-value (fn [_] "qwe")))
=> #'user/bla
=> (def a "asd")
=> #'user/a
=> (bla #'a)
=> "qwe"
=> a
=> "qwe"
但这不是Vars(用def
定义的东西)应该如何在Clojure中起作用的。 def
用于在Clojure中声明绑定,而不是变量。 Binding 意味着您将某个值绑定到某个名称,并且以后不会更改,例如该绑定是不可变的。程序中的其他功能可能会转发不可变性,因此请不要在代码中使用alter-var-root
或其他更改绑定的方法。
如果您确实需要某种具有可变状态的变量 - 请使用atoms
。
我建议你阅读"Clojure for brave and true",其中包含有关该主题的非常简洁的解释。
关于“使用Def命名值”部分下的def
here。
讨论了原子,变种和国家管理here。
P.S。您可以使用this online repl来测试上面的代码。
答案 1 :(得分:1)
如果有问题的 var 以前是def
(声明)dynamic
,你可以让它得到它,让我们说[时间|保持不变性]使用以下新值进行渲染:
编辑:参考例如here
(def ^:dynamic x 5) ;; =>#'user/x
(def ^:dynamic y 3) ;; =>#'user/y
x ;=> 5
y ;=> 3
(binding [x 2 y 7] (+ x y)) ;=> 9
(+ x y) ;=> 8
(defn add-val [] (+ x y)) ;=>#'user/add-val
(binding [x 3 y 7] (add-val)) ;=> 10
(+ x y) ;=> 8 x y still immutable values