跳轉到內容

通用 Lisp/高階主題/包

來自華夏公益教科書,開放的世界,開放的書籍

包是通用 Lisp 中用於劃分名稱空間的功能。包允許將所有函式、宏和變數定義與系統中的其他部分隔離開來。這減少了由於名稱衝突而導致的問題,即兩個人使用相同名稱來表示不同事物。

符號的列印形式為 PACKAGE-NAME::SYMBOL-NAME,但是,如果我們當前在包 PACKAGE-NAME 中,則印表機只會列印 SYMBOL-NAME。動態變數 *PACKAGE* 始終指定當前包。當被內聯時,符號會被內聯到 *PACKAGE* 命名的包中,除非包名稱透過 '::' 符號指定。

包透過 DEFPACKAGE 定義。包可以匯出其任何符號,在這種情況下,它們可以被指定為 PACKAGE-NAME:SYMBOL-NAME,即只有一個 ':'。包也可以從任何其他包中匯入符號。如果匯入的符號與已經內聯到包中的另一個相同名稱的符號相同,則會發生錯誤。您必須選擇一個符號。USE-PACKAGE 幫助匯入包中的 API。包匯出的符號以及包使用的包可以透過 DEFPACKAGE 指定。

示例:列出包中的所有符號

[編輯 | 編輯原始碼]

通用 Lisp 提供了一些宏來迭代包中的符號。兩個最有趣的宏是:DO-SYMBOLS 和 DO-EXTERNAL-SYMBOLS。DO-SYMBOLS 迭代包中可訪問的符號,而 DO-EXTERNAL-SYMBOLS 僅迭代外部符號(您可以將它們視為真正的包 API)。

要列印名為 "PACKAGE" 的包的所有匯出符號,您可以編寫

(do-external-symbols (s (find-package "PACKAGE"))
  (print s))

您也可以透過編寫將所有這些符號收集到一個列表中

(let (symbols)
  (do-external-symbols (s (find-package "PACKAGE"))
    (push s symbols))
  symbols)

或者,您可以使用 LOOP 來完成。

(loop for s being the external-symbols of (find-package "PACKAGE")
      collect s)

版權所有 © 2002-2005 通用 Lisp 食譜專案 http://cl-cookbook.sourceforge.net/

華夏公益教科書