clojure 新手指南(13):序列&向量

序列

咱們知道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

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")
相關文章
相關標籤/搜索