2015-06-20 28 views
3

我是Clojure的新手,我读过它是一种功能性语言。它说,Clojure没有变量,当我发现(定义5)时,它和变量有什​​么区别?关于Vars Clojure的问题

我可以改变var后的值,所以它真的不同于变量吗?我不明白区别。

回答

5

假设由variable你说的是指一个可变的存储位置,我想最主要的区别(这取决于对哪种语言你比较)是,如果你动态地重新绑定Clojure中的var是在每个线程的基础。

但长时间的答案是,你通常不会在Clojure中使用var,除非你真的需要引用一个可变的存储位置。

Clojure赞成使用而不是参考文献的不变性和编程。

您可以观看Rich Hickey's talk关于值。

总结是,当你在Clojure中编程时,你所拥有的是,而不是引用可能会改变的位置(甚至可能被另一个线程改变)。

所以。

(let [a 1 
     _ (println a) => prints 1 
     a 2 
     _ (println a) => prints 2 
    ]) 

即使你在代码“改变a”的,你不改变“老” a的错觉,你只是有一个新的价值。 (如果有人会看第一个定义,它仍然会看到值1)。

实际上,您可以看到作为组合函数调用的作业顺序调用,其中a被作用域中的替换,但根本不是相同的“变量”。

((fn [a] 
    (println a) => prints 1 
    ((fn [a] 
     (println a) => prints 2 
    ) 2) 1) 

尽管如此,如果你需要有许多潜在的线程访问该存储,Clojure gives youvarsatomsrefs

2

这是不正确的,Clojure中没有变量可变存储, 一世。即可变参考。但是,在计算过程中,它们不能用于存储和查找,这些计算可以建模为纯数学函数。

不变性的概念是处理具体的价值,而不是一个或其他人可以改变的引用。就像1是一个值,你不能改变,在Clojure矢量[3 2]是你也不能改变的价值。例如,如果你的算法需要追加1到那个向量,它需要创建一个新的向量,让原来的向量完好无损,而在命令式语言中,你可以“改变”向量,打破所有可能依赖它的东西。不变性的外露是你不必担心这一点,并且你的代码变得不太容易出错。

Clojure以这种新创建的值高效地重用其基于的值的大部分内存的方式实现不可变数据结构。它们提供的读写性能(即创建新版本)几乎与其可变对象相同的性​​能特征。您可能想了解更多关于here的信息,Rich Hickey在与Brian Beckmann的对话this中做了一些很好的解释。

0

想想def定义常数。可以通过再次调用def来改变,但您should not do it

关闭变量的东西是agents这是线程安全的。

(def counter (agent 0)) 
(send counter inc) 
@counter 
;;=> 1 

您还可以访问Java类中的变量。

新类

(def object (ClassName.)) 

硒值

(.fieldName object) 

设定值

(set! (.fieldName object) 5) 

的没有变量 “整” 点是让程序自动线程安全的。这是因为线程错误将在该线程上“始终”失败1将告诉变量a为1,线程b告诉a为2,之后失败。这也是使用纯函数的原因 - 没有变量“否”的线程问题。

另请参阅此question:Clojure differences between Ref, Var, Agent, Atom, with examples和这一个Clojure: vars, atoms, and refs (oh my)

在80%以上 - 不是100%处理“”。