咱們知道clojure是Lisp的一種方言,那麼這也意味着對這門語言必然植根於「列表解析」。可是在Clojure中,咱們優先使用"序列"來創造列表和管理列表中的元素。 java
以前咱們說過,Lisp系列語言整個都創建在列表之上。咱們使用"list"函數來建立一個列表,但後面你就會發現建立列表的方式不僅一種。若是你不想讓你列表中的元素被解釋執行,記得引用(quote)一下。 數據結構
=> (list "truck" "car" "bicycle" "plane") ;;建立一個列表 ("truck" "car" "bicycle" "plane") ;;與上面方式等價 => '("truck" "car" "bicycle" "plane") ("truck" "car" "bicycle" "plane") ;;查看列表的類型 =>(class '("truck" "car" "bicycle" "plane")) clojure.lang.PersistentList ;; 給建立的列表綁定一個全局變量 => (def vehicles (list "truck" "car" "bicycle" "plane")) #'user/vehicles ;;查看是不是序列 =>(seq? vehicles) true ;;查看是不是列表 =>(list? vehicles) true ;;查看是不是集合 => (coll? vehicles) true ;;獲取第一個元素 =>(first vehicles) "truck" ;;獲取第二個元素 =>(second vehicles) "car" ;;獲取最後一個元素 =>(last vehicles) "plane" ;;獲取除第一個元素之外的剩下列表 =>(rest vehicles) ("car" "bicycle" "plane") ;;獲取第n個元素 =>(nth vehicles 0) "truck" =>(nth vehicles 1) "car" ;;添加元素 (這只是返回一個新的列表,vehicles 並不會被改變) => (conj vehicles "motorcycles") ("motorcycles" "truck" "car" "bicycle" "plane")
Cons是lisp語言中另外一個相似列表的一種數據結構。術語」cons「意思就是構造一個對(pair),將這些對連接在一塊兒而後造成一個相似列表的數據結構。就像list同樣,cons既是一個類型,也是一個函數,咱們可使用cons來建立這種數據結構。 函數
=>(cons "truck" (list "car" "bicycle" "plane")) ("truck" "car" "bicycle" "plane") =>(class (cons "truck" (list "car" "bicycle" "plane"))) clojure.lang.Cons =>(def vehicles (cons "truck" (list "car" "bicycle" "plane"))) #'user/vehicles =>(seq? vehicles) true =>(list? vehicles) false =>(coll? vehicles) true =>(conj vehicles "motorcycle") ("motorcycle" "truck" "car" "bicycle" "plane") =>(class (conj vehicles "motorcycle")) clojure.lang.Cons =>(cons "motorcycle" vehicles) ("motorcycle" "truck" "car" "bicycle" "plane") =>(class (cons vehicles "motorcycle")) clojure.lang.Cons =>(conj "truck" nil) java.lang.ClassCastException: cannot be cast to clojure.lang.IPersistentCollection =>(cons "truck" nil) ("truck") =>(class (cons "truck" nil)) clojure.lang.PersistentList
注意最後一個例子,是否是看起來很奇怪?當咱們使用cons將一個元素附加到一個列表或者另外一個cons結構上時,返回的仍然是一個cons類型結構。可是當咱們將一個item附加nil上時,返回的倒是list類型。這一點尤爲注意。 性能
向量是除了list和cons以外的另外一個很受歡迎的數據結構,由於它有時用起來有一些獨特的優點。舉個例子,由於向量使用方括號來表示,因此至少從視覺上來講會讓它從大量的圓括號中脫穎而出,提供了更好的可讀性。另外使用向量一般能提供比列表更好的性能優點。 spa
=>(vector "truck" "car" "bicycle" "plane") ["truck" "car" "bicycle" "plane"]
;;一種簡便的建立向量方式,這個不須要「引用」了哦 =>["truck" "car" "bicycle" "plane"] ["truck" "car" "bicycle" "plane"] =>(class ["truck" "car" "bicycle" "plane"]) clojure.lang.PersistentVector =>(def vehicles ["truck" "car" "bicycle" "plane"]) #'user/vehicles =>(seq? vehicles) false =>(list? vehicles) false =>(vector? vehicles) true =>(coll? vehicles) true注意:雖然大多數函數對待向量和列表都會產生相同的結果,但有時候這種假設每每會引入一些問題。看下面例子,注意兩者之間的區別:
=> (conj ["a" "b"] "c") ["a" "b" "c"] => (conj '("a" "b") "c") ("c" "a" "b")