如果变量在Clojure中是不可变的,那么为什么它允许在下面的代码段中重新定义相同的变量:
(ns tutorial.test-immutability-of-variables)
(defn test_if_variables_are_mutable
[]
(def a 1)
(def a 10)
(println (format "Value of a: %d" a) )
)
(test_if_variables_are_mutable)上面的代码编译,o/p是10。
发布于 2022-03-05 11:29:06
Clojure对值和对值的引用进行了区分。Clojure保证值是不可变的。
考虑一下评估您的函数时会发生什么:
(def a 1)当对上面的表单进行计算时,将创建一个Clojure (名称为a和命名空间tutorial.test-immutability-of-variables),并将其绑定到值1。
(def a 10)在计算此表单时,现有的Clojure Var将反弹到值10。
强烈反对在函数中使用def。仅在代码中对顶级窗体使用def。或者,对于一个词汇绑定符号,使用let。
关于所发生的事情的整个故事比我前面所描述的要复杂一些,请参阅参考文献 on Vars。Clojure中还有其他引用类型,如原子。
发布于 2022-03-06 19:03:05
正如另一个答案所指出的,您可以更改全局Var指向的内容,但不能更改原始的值。下面是另一个例子:
(def x 42)
(defn changer-1
[]
(println "changer-1: x - old" x)
(let [x "Goodbye"] ; change a local variable
(println "changer-1: x - new" x)))
(defn caller-1
[]
(newline)
(let [x "Hello"]
(println "caller-1: x - before" x)
(changer-1)
(println "caller-1: x - after " x)))
(defn changer-2
[]
(println "changer-2: x - old" x)
(def x 666) ; reset the global Var (normally bad form)
(println "changer-2: x - new" x))
(defn caller-2
[]
(newline)
(println "caller-2: Var x - before" x)
(let [x "Hello"]
(println "caller-2: x - before" x)
(changer-2)
(println "caller-2: x - after " x))
(println "caller-2: Var x - after" x))
(caller-1)
(caller-2)有结果
-----------------------------------
Clojure 1.10.3 Java 15.0.2
-----------------------------------
caller-1: x - before Hello
changer-1: x - old 42
changer-1: x - new Goodbye
caller-1: x - after Hello
caller-2: Var x - before 42
caller-2: x - before Hello
changer-2: x - old 42
changer-2: x - new 666
caller-2: x - after Hello
caller-2: Var x - after 666有关更多信息,请参见此文件清单源,特别是“获取Clojure”和“勇敢Clojure”。
https://stackoverflow.com/questions/71361280
复制相似问题