Clojure提供了一种函数和宏之外的操作形式,special form. 数量有限,并且不是Clojure语言本身实现的。
主要是下面几个:
catch,def, do, dot ('.'), finally, fn, if, let, loop,
monitor-enter, monitor-exit, new, quote, recur, set!, throw, try 和 var.
完整文档请参考:http://clojure.org/special_forms
这里要解释一下。首先,Clojure因为是函数式编程语言,所以不支持变量,只支持不变量(immutable)。好处是函数的状态不受全局变量的影响,并且在并发编程时不需要锁。那么Clojure在实践中需要支持“变量”怎么办?提供了四种机制,其中一种就是Vars.
Var可以指向一个易变的存储地点(mutable storage location), 绑定的作用就是让一个var指向一个mutable storage location. 如果这个var不再指向任何mutable storage location, 叫做unbound.
def 这种special form就是用来创建一个var,并且将其bind到一个root value。比如下面的代码:
user=> (def x 5) #'user/x这里提供了参数5作为初始值,因此x被创建出来,并被初始化为5,可以这样检查x的值:
user=> x 5
user=> (def y) #'user/y user=> y #<Unbound Unbound: #'user/y>
默认情况下,一个var是static的,所有线程都可以访问。如果想创建线程自己的binding,别的线程无法访问,应该做两件事情:
1.def创建var时指定参数^:dynamic
2.用binding宏来创建自己的线程的binding
参考官方文档的例子:http://clojure.org/vars
By default Vars are static, but per-thread bindings for Vars defined with metadata marking them as dynamic can be established via the macro binding and within-thread they obey a stack discipline: user=> (def ^:dynamic x 1) user=> (def ^:dynamic y 1) user=> (+ x y) 2 user=> (binding [x 2 y 3] (+ x y)) 5 user=> (+ x y) 2http://java.ociweb.com/mark/clojure/article.html#Vars 这篇文章也不错。