跳转到内容

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

华夏公益教科书