向量

向量用方括號表示:

[]
;;=> []

[:foo]
;;=> [:foo]

[:foo :bar]
;;=> [:foo :bar]

[1 (+ 1 1) 3]
;;=> [1 2 3]

另外,使用文字語法,你還可以使用 vector 函式構造向量:

(vector)
;;=> []

(vector :foo)
;;=> [:foo]

(vector :foo :bar)
;;=> [:foo :bar]

(vector 1 (+ 1 1) 3)
;;=> [1 2 3]

你可以使用 vector? 謂詞測試某些內容是否為向量 :

(vector? [])
;;=> true

(vector? [:foo :bar])
;;=> true

(vector? nil)
;;=> false

(vector? 42)
;;=> false

(vector? :foo)
;;=> false

conj 將元素新增到向量的末尾:

(conj [] :foo)
;;=> [:foo]

(conj (conj [] :foo) :bar)
;;=> [:foo :bar]

(conj [] :foo :bar)
;;=> [:foo :bar]

count 以恆定時間返回專案數:

(count [])
;;=> 0

(count (conj [] :foo))
;;=> 1

(count [:foo :bar])
;;=> 2

你可以使用 peek 獲取向量的最後一個元素 :

(peek [])
;;=> nil

(peek [:foo])
;;=> :foo

(peek [:foo :bar])
;;=> :bar

你可以使用 pop 獲得一個沒有最後一個元素的新向量 :

(pop [:foo])
;;=> []

(pop [:foo :bar])
;;=> [:foo]

請注意,如果你嘗試彈出一個空向量,你將獲得一個 IllegalStateException

(pop [])
;; java.lang.IllegalStateException: Can't pop empty vector

與列表不同,向量被索引。你可以使用 get常量時間內通過索引獲取向量的元素 :

(get [:foo :bar] 0)
;;=> :foo

(get [:foo :bar] 1)
;;=> :bar

(get [:foo :bar] -1)
;;=> nil

(get [:foo :bar] 2)
;;=> nil

另外,向量本身是獲取索引並在該索引處返回元素的函式:

([:foo :bar] 0)
;;=> :foo

([:foo :bar] 1)
;;=> :bar

但是,如果你呼叫一個索引無效的向量,你將得到一個 IndexOutOfBoundsException 而不是 nil

([:foo :bar] -1)
;; java.lang.IndexOutOfBoundsException:

([:foo :bar] 2)
;; java.lang.IndexOutOfBoundsException:

你可以使用 assoc 在特定索引處獲取具有不同值的新向量 :

(assoc [:foo :bar] 0 42)
;;=> [42 :bar]

(assoc [:foo :bar] 1 42)
;;=> [:foo 42]

如果傳遞的索引等於向量的 count,Clojure 將新增元素,就像使用了 conj 一樣。但是,如果你傳遞一個負數或大於 count 的索引,你將得到一個 IndexOutOfBoundsException

(assoc [:foo :bar] 2 42)
;;=> [:foo :bar 42]

(assoc [:foo :bar] -1 42)
;; java.lang.IndexOutOfBoundsException:

(assoc [:foo :bar] 3 42)
;; java.lang.IndexOutOfBoundsException:

你可以使用 seq 獲取向量中的一系列專案:

(seq [])
;;=> nil

(seq [:foo])
;;=> (:foo)

(seq [:foo :bar])
;;=> (:foo :bar)

由於向量被索引,你還可以使用 rseq 獲得向量項的反轉序列 :

(rseq [])
;;=> nil

(rseq [:foo])
;;=> (:foo)

(rseq [:foo :bar])
;;=> (:bar :foo)

請注意,儘管所有列表都是序列,並且序列的顯示方式與列表相同,但並非所有序列都是列表!

'(:foo :bar)
;;=> (:foo :bar)

(seq [:foo :bar])
;;=> (:foo :bar)

(list? '(:foo :bar))
;;=> true

(list? (seq [:foo :bar]))
;;=> false

(list? (rseq [:foo :bar]))
;;=> false