Clojure里面是不支持变量的。Binding跟变量有点像,但是在被赋值之前是不允许改的,包括:全局binding, 线程本地(thread local)binding, 以及函数内的本地binding, 以及一个表达式内部的binding。

def 这个special form 定义一个全局的 binding,并且你还可以给它一个”root value” ,这个root value在所有的线程里面都是可见的,除非你给它赋了一个线程本地的值.def。也可以用来改变一个已经存在的binding的root value —— 但是这是不被鼓励的,因为这会牺牲不可变数据所带来的好处。

函数的参数是只在这个函数内可见的本地binding。

let 这个special form 创建局限于一个 当前form的bindings. 它的第一个参数是一个vector, 里面包含名字-表达式的对子。表达式的值会被解析然后赋给左边的名字。这些binding可以在这个vector后面的表达式里面使用。这些binding还可以被多次赋值以改变它们的值,let命令剩下的参数是一些利用这个binding来进行计算的一些表达式。注意:如果这些表达式里面有调用别的函数,那么这个函数是无法利用let创建的这个binding的。

宏 binding let 类似, 但是它创建的本地binding会暂时地覆盖已经存在的全局binding. 这个binding可以在创建这个binding的form以及这个form里面调用的函数里面都能看到。但是一旦跳出了这个binding 那么被覆盖的全局binding的值会回复到之前的状态。

从 Clojure 1.3开始, binding只能用在 动态变量(dynamic var)上面了. 下面的例子演示了怎么定一个dynamic var。另一个区别是let 是串行的赋值的, 所以后面的binding可以用前面binding的值, 而binding 是不行的.

要被用来定义成新的、本地线程的、用binding来定义的binding有它们自己的命名方式:她们以星号开始,以星号结束。在这篇文章里面你会看到:*command-line-args*,*agent*,*err*,*flush-on-newline*,*in*,*load-tests*,*ns*,*out*,*print-length*,*print-level* and*stack-trace-depth*.要使用这些binding的函数会被这些binding的值影响的。比如给*out*一个新的binding会改变println函数的输出终端。

下面的例子介绍了def,let 和binding的用法:

[python] view plaincopy print?
  1. ; clojure connect to mysql
  2. ; ithomer.net
  3. ; 2013.12.10
  4. (ns myClojure.syntax.binding)
  5. (def ^:dynamic v 1)         ; v is a global binding
  6. (defn f1 []
  7. (println "f1: v =" v))    ; global binding of 1
  8. (defn f2 []
  9. (println "f2: before let v =" v)       ; global binding
  10. (let [v 2]                             ; creates local binding v that shadows global one
  11. (println "f2: in let, v =" v)        ; local binding of 2
  12. (f1))                                ; of 1
  13. (println "f2: after let v =" v))       ; global binding of 1
  14. (defn f3 []
  15. (println "f3: before binding v =" v)   ; global binding of 1
  16. (binding [v 3]                         ; same global binding with new, temporary value
  17. (println "f3: in binding, v =" v)    ; global binding of 3
  18. (f1))                                ; of 3
  19. (println "f3: after binding v =" v))   ; global binding of 1
  20. (defn f4 []
  21. (def v 4)                               ; changes the value of the global binding
  22. (println "f4: after binding v =" v)     ; of 4
  23. (f1))                                   ; of 4
  24. (f2)
  25. (f3)
  26. (f4)
  27. (println "after calling f4, v =" v)      ; of 4

运行结果:

[html] view plaincopy print?
  1. f2: before let v = 1
  2. f2: in let, v = 2
  3. f1: v = 1
  4. f2: after let v = 1
  5. f3: before binding v = 1
  6. f3: in binding, v = 3
  7. f1: v = 3
  8. f3: after binding v = 1
  9. f4: after binding v = 4
  10. f1: v = 4
  11. after calling f4, v = 4

参考推荐:

Clojure入门教程

Clojure 基本语法

Clojure 学习入门(13)- binding相关推荐

  1. Clojure 学习入门(6)- 函数定义

    一.创建函数:  fn: fn是一个宏,用于定义一个简单的函数,如下:  [python] view plaincopy print? user=> (fn [] "hello&quo ...

  2. Clojure 学习入门(6)—— 函数定义

    一.创建函数: fn: fn是一个宏,用于定义一个简单的函数,如下:  user=> (fn [] "hello") #<user$eval375$fn__376 us ...

  3. Clojure 学习入门(14)- 循环控制

    Clojure 基于函数的流程控制  repeatedly 字面意思为重复函数.一般的用法如下: user=> (repeatedly 5 #(rand-int 11)) (6 8 2 6 6) ...

  4. Clojure 学习入门(1) - 学习资料

    转自:http://blog.csdn.net/ithomer/article/details/17225813 Clojure(发音类似"closure",['kləʊʒə(r) ...

  5. Clojure 学习入门(15)- 条件判断

    一.标准的流程控制  if:  将一个判断表达式作为它的第一个参数进行求值.如果求值为true,那么就返回它的第二个参数(相当于"then"子句)的求值结果.如果结果为false( ...

  6. python中字典的value可以为任意对象_Python学习入门(13)—字典

    (本号正在连续推出以Python官网文档为主线的系统学习Python的系列文章或视频,感兴趣的朋友们欢迎搜索关注.在这里学习Python事半功倍!本文及后续文章如无特别声明均以Windows平台作为演 ...

  7. Clojure 学习入门(17)- 异常处理

    异常处理  Clojure代码里面抛出来的异常都是运行时异常.当然从Clojure代码里面调用的Java代码还是可能抛出那种需要检查的异常的. try - catch - finally 以及thro ...

  8. Clojure 学习入门(16)- 正则表达式

    一.创建正则表达式  re-pattern函数:  函数 (re-pattern) 接受一个字符串参数,返回一个正则表达式样式(java.util.regex.Pattern类的实例).这个样式能用于 ...

  9. Clojure 学习入门(12)- map/pmap

    clojure map数据结构的常用方法,小结一下 map 各种排序 [html] view plaincopy print? (println (sorted-map-by > 1 " ...

最新文章

  1. 假设检验_python 重点
  2. 在windows sever 2008系统中如何添加桌面体验功能
  3. python3.6安装-Linux安装python3.6
  4. Intel DPDK包部署试验
  5. dbda.class.php 下载,DBDA
  6. poj 3608 旋转卡壳求不相交凸包最近距离;
  7. web页面--前端明水印
  8. 如何用 Swift 语言构建一个自定控件
  9. JS 获取浏览器信息,给出友情提示,避免部分兼容性问题
  10. LeetCode 1905. 统计子岛屿(BFS)
  11. mysql 字段等于select_mysql_select_计算字段_数据处理函数_5
  12. ARMv8体系结构基础02:搭建实验环境
  13. 我的blog终于开张啦 :)
  14. 商业流程中的traversedpath
  15. SpringCloud与Ribbon整合的时候是如何提供RestTemplate负载均衡功能?
  16. linux服务器上配置二级域名
  17. matlab运行.m文件的命令,怎样在matlab的命令窗口运行.m文件
  18. 你的另一半眼泪流给谁
  19. 百度百科首页登录入口在哪,个人如何创建百度百科
  20. C++11的更新内容--auto--右值引用和移动构造--1114

热门文章

  1. Java从零开始学三十六(JAVA IO- 字符流)
  2. 一则 gfs2 集群文件系统无法挂载的解决案例
  3. Flex 国际化使用
  4. SCCM 2012 简体中文正式版 部署文档 01 环境说明
  5. 空位補零,你會選擇哪種方式?
  6. Jenkins 持续集成CICD
  7. 网页header 的 meta使用
  8. AngularJS 开发辅助工具
  9. 从声学模型算法角度总结 2016 年语音识别的重大进步
  10. java 文件名乱码_详解关于java文件下载文件名乱码问题解决方案