clojure 向量

示例

向量用方括号表示:

[]
;;=> []

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