矢量
矢量用方括号表示:
[]
;;=> []
[: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