矢量

矢量用方括号表示:

[]
;;=> []

[: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