屬性清單

普通列表對於表示元素序列很有用,但有時表示一種鍵值對映更有幫助。Common Lisp 提供了幾種方法,包括真正的雜湊表(參見 18.1 雜湊表概念 )。在 Common Lisp 中有兩種主要方式或表示值對映的鍵: 屬性列表關聯列表 。此示例描述了屬性列表。

屬性列表或 plist 是一個普通列表,其中交替值被解釋為鍵及其關聯值。例如:

(defparameter *ages* (list 'john 34 'mary 23 'tim 72))

可以被視為屬性列表,其將表示個人姓名的符號與表示年齡的整數對映。可以使用簡單列表函式(如 member) 實現一些檢索功能。例如,要檢索約翰的年齡,可以寫

(second (member 'mary *age*))
;=> 23

所述構件函式返回開頭的列表的尾部瑪麗,也就是 (瑪麗 23 添 72) ,和第二返回該列表的第二個元素,即 23 。雖然這是訪問屬性列表中的值的一種方法,但像屬性列表這樣的約定的目的是從底層表示(列表)中抽象出來,並提供用於處理資料結構的更高階函式。

對於屬性列表,檢索函式是 getf ,它接受屬性列表,一個鍵(通常稱為指示符 ),以及在屬性列表不包含鍵值的情況下返回的可選預設值。

(getf *ages* 'tim)
;=> 72

(getf *ages* 'bob -1)
;=> -1

要更新屬性列表中的值,可以使用 setf 。例如,當約翰的生日到來並且他的年齡增加時,可以執行以下任一操作:

(setf (getf *ages* 'john) 35)

(incf (getf *ages* 'john))

incf 適用於這種情況,因為它基於 setf

要在屬性列表中查詢多個屬性,請使用 get-properties

所述 GETF 功能通過列表搜尋從左至右,這意味著是能夠掩模值的屬性列表,而無需從一個列表中去除它們或更新的任何列表中的結構。例如,使用 list *

(defvar *ages* '(john 34 mary 23 tim 72))

(defvar *new-ages* (list* 'mary 29 *ages*))

*new-ages*
;=> (mary 29 john 34 mary 23 tim 72)

現在,對 mary 的查詢將返回第一個條目:

(getf *new-ages* 'mary)
;=> 29