Clojure语言六:def & var

special form

Clojure提供了一种函数和宏之外的操作形式,special form. 数量有限,并且不是Clojure语言本身实现的。

主要是下面几个:

catch,defdodot ('.'), finallyfnifletloop

monitor-entermonitor-exitnewquoterecurset!throwtry 和 var.

完整文档请参考:http://clojure.org/special_forms

Vars 变量

这里要解释一下。首先,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


如果初始值参数没有提供,那么def创建了var但是没有bind它,也就是unbound状态:

user=> (def y)
#'user/y
user=> y
#


var有一个root binding的概念。也就是所有线程都共享的binding。如果线程有自己的binding,就不再使用root binding。

默认情况下,一个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)
2
http://java.ociweb.com/mark/clojure/article.html#Vars 这篇文章也不错。








你可能感兴趣的:(Clojure)