为什么 Clojure 允许我重新定义同一个变量?
如果变量在 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。
If the variables are immutable in Clojure, then why did it allow to redefine the same variable in the following snippet:
(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)
The above code compiles and o/p is 10
.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
Clojure 区分值和对值的引用。 Clojure 保证值是不可变的。
考虑一下当你的函数被求值时会发生什么:
当上面的形式被求值时,会创建一个 Clojure Var(名称为
a
和命名空间tutorial.test-immutability-of-variables
) 并且它绑定到值 1。当计算此形式时,现有的 Clojure Var 会反弹到值 10。
强烈建议不要在函数中使用
def
。仅在代码中对顶级表单使用def
。或者,对于词法绑定符号,请使用let
。所发生的事情的完整情况比我上面概述的要复杂一些,请参阅参考文档在瓦尔斯上。 Clojure 中还有其他引用类型,例如 Atoms。
Clojure makes a distinction between values and references to values. Clojure guarantees that values are immutable.
Consider what happens when your function is evaluated:
When the above form is evaluated, a Clojure Var is created (with name
a
and namespacetutorial.test-immutability-of-variables
) and it is bound to the value 1.When this form is evaluated, the existing Clojure Var is rebound to the value 10.
Use of
def
within a function is strongly discouraged. Usedef
for top level forms only in your code. Alternatively for a lexically bound symbol uselet
.The full story of what happens is a bit more involved than I've outlined above, see the reference documentation on Vars. There are other reference types in Clojure, such as Atoms.
正如另一个答案指出的那样,您可以更改全局
Var
指向的内容,但无法更改原始值。这是另一个示例:有关结果的
更多信息,请参阅此文档列表 来源,特别是“Getting Clojure”和“Brave Clojure”
As the other answer points out, you can change what the global
Var
points to, but you cannot change the original value. Here is another example:with result
For more information, please see this list of documentation sources, especially "Getting Clojure" and "Brave Clojure"