为什么我可以在 Clojure 中更改不可变变量?
Why can I change immutable variables in Clojure?
我来自 Javascript 世界,那里使用 const 来声明不可变变量。
不可变变量的定义在 Clojure 中以相同的方式解释。
但是,这是允许的:
(def cheese "I like cheese")
...
...
(def cheese "Actually, I changed my mind)
当我 运行 这个时,repl 给了我 actually, I changed my mind
。
在JS中会报错,因为aconst
不能改
如果有人能解释一下我对 immutable variables
在 clojure 世界中的理解不正确的地方,我将不胜感激?
谢谢
准确地说,Clojure 有不可变值,而不是不可变变量。毕竟,名称 Var
是 shorthand 的“变量”。
想象一下这个数字 5
。你永远不需要担心谁“拥有”它,或者有人可能会改变它的定义。此外,在您的程序的许多部分中,可以有多个用于多种用途的该编号的多个副本。 Clojure 将这个想法扩展到集合值,例如向量 [1 2 3]
或映射 {:first "Joe" :last "Cool"}
.
话虽如此,在 Clojure 中,Var
通常用于永远不会更改(尽管它可以)的全局“常量”值。对于确实发生变化的值,使用 Clojure Atom
(全局或局部)是正常的。还有许多其他选项(例如 reduce
等函数有一个内部累加器)。
list of documentation sources 是一个很好的起点,尤其是“Getting Clojure”和“Brave Clojure”两本书。
正如 Alan 提到的,Clojure 具有不可变的值,而不是不可变的变量。
当你执行
(def x 42)
创建了一个 Clojure Var
,Var 绑定到名称(又名符号)x
,并且不可变值 42
被放置在 Var 中. Var 是值的容器。通常,一个 Var 中只会放置一个值。但是,在您的示例中,在不同时间 Var 中可以放置不同的不可变值。
阅读 Clojure Vars and the Global Environment 可能会有帮助。
我来自 Javascript 世界,那里使用 const 来声明不可变变量。
不可变变量的定义在 Clojure 中以相同的方式解释。
但是,这是允许的:
(def cheese "I like cheese")
...
...
(def cheese "Actually, I changed my mind)
当我 运行 这个时,repl 给了我 actually, I changed my mind
。
在JS中会报错,因为aconst
不能改
如果有人能解释一下我对 immutable variables
在 clojure 世界中的理解不正确的地方,我将不胜感激?
谢谢
准确地说,Clojure 有不可变值,而不是不可变变量。毕竟,名称 Var
是 shorthand 的“变量”。
想象一下这个数字 5
。你永远不需要担心谁“拥有”它,或者有人可能会改变它的定义。此外,在您的程序的许多部分中,可以有多个用于多种用途的该编号的多个副本。 Clojure 将这个想法扩展到集合值,例如向量 [1 2 3]
或映射 {:first "Joe" :last "Cool"}
.
话虽如此,在 Clojure 中,Var
通常用于永远不会更改(尽管它可以)的全局“常量”值。对于确实发生变化的值,使用 Clojure Atom
(全局或局部)是正常的。还有许多其他选项(例如 reduce
等函数有一个内部累加器)。
list of documentation sources 是一个很好的起点,尤其是“Getting Clojure”和“Brave Clojure”两本书。
正如 Alan 提到的,Clojure 具有不可变的值,而不是不可变的变量。
当你执行
(def x 42)
创建了一个 Clojure Var
,Var 绑定到名称(又名符号)x
,并且不可变值 42
被放置在 Var 中. Var 是值的容器。通常,一个 Var 中只会放置一个值。但是,在您的示例中,在不同时间 Var 中可以放置不同的不可变值。
阅读 Clojure Vars and the Global Environment 可能会有帮助。