清單

列表用括號表示:

()
;;=> ()

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