引用类型
引用类型是一种可变引用指向不可变数据的一种机制。Clojure里面有4种引用类型:Vars,Refs,Atoms和Agents. 它们有一些共同的特征:
- 它们都可以指向任意类型的对象。
 - 都可以利用函数 
deref以及宏@来读取它所指向的对象。 - 它们都支持验证函数,这些函数在它们所指向的值发生变化的时候自动调用。如果新值是合法的值,那么验证函数简单的返回true, 如果新值是不合法的,那么要么返回false, 要么抛出一个异常。如果只是简单地返回了 
false, 那么一个IllegalStateException异常会被抛出,并且带着提示信息: "Invalid reference state" 。 - 如果是Agents的话,它们还支持watchers。如果被监听的引用的值发生了变化,那么Agent会得到通知, 详情见 "Agents" 一节。
 
下面的这个表格总结了一下四种引用类型的区别,以及分别要用什么方法去创建或者修改它们。这个表格里面提到的函数我们会在后面介绍。
| Var | Ref | Atom | Agent | |
|---|---|---|---|---|
| 目的 | 同步对于一个线程本地(thread-local)的变量的修改。 | 同步、协调对于一个或者多个值的修改 | 同步对于一个值的修改 | 对一个值进行异步修改 | 
| 创建方法 | (def name initial-value) | 
(ref initial-value) | 
(atom initial-value) | 
(agent initial-value) | 
| 修改方法 | (def name new-value) - 可以赋新的值 (alter-var-root (var name) update-fn args)  - 自动设置新值 (set! name new-value) - 在一个binding form 里满设置一个新的、线程本地的值 | 
(ref-set ref new-value) - 必须在dosync里面调用  (alter ref update-fn arguments) - 必须在dosync里面调用 (commute ref update-fn arguments) - 必须在 dosync 里面调用 | 
(reset! atom new-value)  (compare-and-set! atom current-value new-value) (swap! atom update-fn arguments) | 
(send agent update-fn arguments)   (send-off agent update-fn arguments) |