在Clojure中,咱们可使用 " def " 给函数和数据赋予一个名字。例如咱们定义一个叫作“alphabet”的字符串变量 shell
user=> (def alphabet "abcdefghijklmnopqrstuvwxyz") #'user/alphabet user=> alphabet "abcdefghigklmnopqrstuvwxyz"
使用变量的好处一个是方便使用,另外一个在于一个有意义的名字大大加强代码的可读性。举个例子,若是咱们想要知道一个字符串的包含的字符数量: app
user=> (count alphabet) 26咱们就不须要在每次去计算字符串数量的时候都要写下长长的一大串了。只用把与该字符串绑定的变量名传过去就行。使用变量绑定,咱们不只能使代码具备良好的可读性,有时候还能增长代码性能。
增长性能?这个很好理解也很经常使用。例如咱们常常把计算好的值绑定到一个变量上。这样咱们在用到这个值的时候就不用每次都得从新计算了。对于一些费时的操做,这可能省下大量的时间。下面的例子就说明了这一点: 函数
user=> (def alphabet-length (count alphabet)) user=> alphabet-length 26若是咱们要计算字符串长度的两倍,就能够直接使用绑定的字符串长度:
user=> (+ alphabet-length alphabet-length) 52使用def绑定相似其余语言中的赋值操做。
首先咱们看下面这个例子: 性能
user=> (def alphabet "abcdefghijklmnopqrstuvwxyz") ;;将aplhabet绑定到一个字符串 #'user/alphabet user=> (def alphabet-length (count apphabet)) ;;将alphabet-length与长度绑定 user=> alphabet ;;此时为26 26 user=> (def alphabet "abc") ;;从新绑定到新的字符串 user=> alphabet ;;依然是26,没有变化 26上面例子中,咱们改变alphabet后,alphabet-length是没有变化的。固然对于上面例子来讲,没有变化是正常的。可是咱们如何能让alphabet的变化能体如今alphabet-length上呢?这就须要函数绑定了。
咱们可使用关键字 " fn " 来定义一个匿名函数。 spa
user=> (fn[](count alphabet)) ;;这里定义了一个匿名函数 user$eval6036$fn__6037 user$eval6036$fn__6037@6e3ebbb0 user=> (def alphabet-length (fn[](count alphabet))) ;;这里定义了一个一样的匿名函数,不过绑定到了alphabet-length上 #'user/alphabet-length上面有一个注意点,函数中使用的alphabet是咱们以前已经绑定好的。使用def的绑定属于全局绑定,就是说对于其余函数是可见的。在clojure中,函数总会有一个返回值,那就是函数体的执行能到达的最后一个表达式。因此上面定义的匿名函数最终会返回alphabet的长度。咱们将匿名函数绑定到了alphabet-length上,每次咱们输入alphabet的时候,都会去执行这个匿名函数。因此咱们只要去改变alphabet的值,由于这种改变时全局的,alphabet-length都会从新计算成新的字符串长度。看下面例子:
user=> alphabet-length ;;不执行函数,返回函数字面量 user$alphabet_length user$alphabet_length@71d408f7 user=> (alphabet-length) ;;执行函数,返回函数执行结果 3咱们在使用绑定函数的时候要注意,此时alphabet-length是与函数绑定的,换句话说它表明的是一个函数。在clojure中,函数的调用必需要在S表达式中。若是直接使用函数名,会返回函数的字面量,并不会执行函数。
咱们再来看一下如何绑定须要传参的匿名函数。咱们定义一个两个数字相加的匿名函数,并绑定到add上: code
user=> (def add (fn [a,b](+ a b))) ;; fn后的[]内放置参数列表,多个参数用逗号分隔 user=> (add 1 2) 3
clojure提供了一种比较简洁的方式让咱们来对匿名函数进行绑定 字符串
;; 将 (fn (count alphabet)) 替换成了#(count alphabet) ,省了几个括号 user=> (def alphabet-length #(count alphabet)) #'user/alphabet-length再看一下须要参数传递的例子(很是简洁)
;;这里的参数直接使用%,若是只有一个参数只用 "%"便可。多个参数是 "%[参数序号]" user=> (def add #(+ %1 %2)) user=> (add 1 2) 3