在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