最近在看storm的原始碼,就學習分享下clojure語法。
閱讀目錄:
概述
clojure是一種執行在JVM上的Lisp方言,屬於函數語言程式設計正規化,它和java可以方便的互相呼叫,這樣開發的程式可以很好的結合java和clojure的優點(storm),這跟Net中C#和F#的角色一樣。
安裝java1.6以上的JDK,下載地址。
下載clojure的環境 包,下載地址。
解壓後用命令列進入到clojure目錄下,輸入下面命令進入REPL命令列互動介面:
java -cp clojure-1.7.0.jar clojure.main
歡迎進入clojure的世界。
變數
Clojure中的變數可以def關鍵字來宣告:
clojure資料型別是弱型別,對應java中的object,然後通過變數名直接呼叫。
類似c#中程式碼:
object greet = "Good Morning"; Console.WriteLine(greet);
Clojure語法是把程式碼元素用小括號形式括起來,以空格來分割元素,使其像填充列表一樣來編寫程式碼。
(str "Hello World!")
函數語言程式設計中以函式為第一類物件,其小括號後面第一個元素被Clojure直譯器當成一個函式或巨集,其後面的都會被當成引數,如上"hello world"是被當成引數傳入str函式進行輸出。
類似C#程式碼:
Console.WriteLine("Hello World!");
一個變數可以重複賦值,也可以是不同型別:
def可以把函式賦值給一個變數,函式變數不能直接呼叫,需要加上括號:
類似c#程式碼:
Action func = () => { Console.WriteLine("Hello World"); }; func();
運算子
clojure使用前置運算子,分號(;)表示後面跟的是註釋。
加減乘除:
(+ 1 1) ; => 2 (- 2 1) ; => 1 (* 1 2) ; => 2 (/ 2 1) ; => 2
增量,接受一個數值加1後範圍,類似C#中的i++。
(inc 5) ;=>6
減量:
(dec 5) ;=>4
求商函式:
(quot 5 2) ;=>2
求餘函式:
(quot 5 2) ;=>1
小於(<):
(< 5 6) ;=>true
小於等於 (<=):
(<= 5 5) ;true
大於(>):
(> 8 5) ;=>true
大於等於 (>=) :
(<= 5 5) ;true
等號 =
(= 1 1) ; => true (= 2 1) ; => false (= 1 "1") ;=> false
同樣的把前置運算子理解為函式,後面為引數。
函式
clojure中以函式為第一類物件,其小括號後面第一個元素被Clojure直譯器當成一個函式或巨集,其後面的都會被當成引數。 定義函式用defn,跟定義變數的def類似:
(defn Get [] "Hello World") ;=>"Hello World"
下面定義了get函式,中括號為函式的引數,輸出Hello World字串。加引數後,再次呼叫需要傳入值,如果不傳會報異常。
下面在函式內部使用a函式引數,如果想要拼接的話,可以在內部使用str函式,用它返回的值當成Get函式的引數:
多個參數列示形式:[arg1,arg2]
流程控制
判斷if
這裡有三層巢狀,首先(= age 18)來判斷返回是否等於18,作為if判斷該返回哪個字串的依據,再根據if確定的字串作為函式的返回值。 注意if是不是函式或巨集,而是叫做special form(特殊形式),而且沒有else,用空白或換行即表示else,不用顯式return,clojure會將最後一個表示的值作為函式的返回值。
謂詞函式
謂詞函式是一個判斷式,一個返回bool值的函式或者仿函式,用來測試條件是否成立。
與或非(and or not):
clojure中(lisp習慣)有個規定:對於判斷功能的函式,函式名後面都有一個“?”號。所以只要看到後面帶問號的函式名,就知道這一定是一個判斷語句。
user=> (fn? quot) ;判斷quot是不是一個函式true
user=> (fn? 1) ;判斷1是不是一個函式 false
測試一個物件的型別的謂詞:class?,coll?,decimal?,delay?,float?,fn?,instance?,integer?,isa?,keyword?,list?,macro?,map?,number?,seq?,set?,string?,vector?。
測試兩個值之間關係的謂詞有:<,<=,=,not=,==,>,>=,compare,distinct? , identical?。
測試邏輯關係的謂詞有:and,or,not,true?,false?,nil?。
測試數字的謂詞有:even?,neg?,odd?,pos?,zero?。
總結
Clojure裡面的每個操作被實現成以下三種形式:
- 函式(function) 文中以defn定義的。
- 巨集(macro) Clojure中幾乎所有的函式和巨集都是用Clojure程式碼實現的,關於巨集後面再說。
- special form 文中出現的if就是,其他還包括catch,def,do,dot (‘.’),finally,fn,if,let,loop,monitor-enter,monitor-exit,new,quote,recur,set!,throw,try,var。
部落格園的程式碼高亮不支援Clojure。
[0] http://clojure.org/[1] http://xumingming.sinaapp.com/302/[2] http://huangz.iteye.com/blog/1325228[3] http://segmentfault.com/a/1190000000414279#articleHeader0