通用 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/