在Clojure中,如何更改(def)函数内的变量值

时间:2018-02-08 16:52:46

标签: clojure

所以,我刚开始学习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”作为值。 有可能吗?

感谢您的帮助!

2 个答案:

答案 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