清單
列表用括號表示:
()
;;=> ()
Clojure 列表是單連結串列 。conj
聯合一個新元素到最高效的位置集合。對於列表,這是在開頭:
(conj () :foo)
;;=> (:foo)
(conj (conj () :bar) :foo)
;;=> (:foo :bar)
與其他集合不同,非空列表在評估時被評估為對特殊表單,巨集或函式的呼叫。因此,雖然 (:foo)
是包含:foo
作為其唯一專案的列表的文字表示,但是在 REPL 中評估 (:foo)
將導致 IllegalArgumentException
被丟擲,因為關鍵字不能被呼叫為 nullary 函式 。
(:foo)
;; java.lang.IllegalArgumentException: Wrong number of args passed to keyword: :foo
為了防止 Clojure 評估非空列表,你可以知道它:
'(:foo)
;;=> (:foo)
'(:foo :bar)
;;=> (:foo :bar)
不幸的是,這會導致不評估元素:
(+ 1 1)
;;=> 2
'(1 (+ 1 1) 3)
;;=> (1 (+ 1 1) 3)
出於這個原因,你通常希望使用 list
,一個可變引數函式 ,用於計算其所有引數並使用這些結果構造一個列表:
(list)
;;=> ()
(list :foo)
;;=> (:foo)
(list :foo :bar)
;;=> (:foo :bar)
(list 1 (+ 1 1) 3)
;;=> (1 2 3)
count
以恆定時間返回專案數:
(count ())
;;=> 0
(count (conj () :foo))
;;=> 1
(count '(:foo :bar))
;;=> 2
你可以使用 list?
謂詞測試某些內容是否為列表 :
(list? ())
;;=> true
(list? '(:foo :bar))
;;=> true
(list? nil)
;;=> false
(list? 42)
;;=> false
(list? :foo)
;;=> false
你可以使用 peek
獲取列表的第一個元素 :
(peek ())
;;=> nil
(peek '(:foo))
;;=> :foo
(peek '(:foo :bar))
;;=> :foo
你可以使用 pop
獲取沒有第一個元素的新列表 :
(pop '(:foo))
;;=> ()
(pop '(:foo :bar))
;;=> (:bar)
請注意,如果你嘗試將空列表清空,你將得到一個 IllegalStateException
:
(pop ())
;; java.lang.IllegalStateException: Can't pop empty list
最後,所有列表都是序列,因此你可以使用可以對任何其他序列執行的列表執行所有操作。實際上,除了空列表之外,在列表上呼叫 seq
會返回完全相同的物件:
(seq ())
;;=> nil
(seq '(:foo))
;;=> (:foo)
(seq '(:foo :bar))
;;=> (:foo :bar)
(let [x '(:foo :bar)]
(identical? x (seq x)))
;;=> true