:从Common Lisp中的软件包导出

时间:2019-06-30 09:01:08

标签: package export common-lisp

我已经定义了一个类似于以下的程序包:

(defpackage :thehilariouspackageofamirteymuri
  (:nicknames ampack amir teymuri)
  (:use common-lisp)
  (:export say-hi-to))
(in-package :amir)

(defun say-hi ()
  "Docstring"
  "Hello")

(defun say-hi-to (who)
  (concatenate 'string (say-hi) " " who " from " (package-name *package*) "!"))

现在更改为包,也可以访问#'say-hi:

(in-package :amir)
(say-hi) ; -> "Hello"
(say-hi-to "World") ; -> "Hello World from THEHILARIOUSPACKAGEOFAMIRTEYMURI!"

export关键字不是在告诉将事情外部化吗?为什么非外部的“'say-hi”也被导出?

2 个答案:

答案 0 :(得分:5)

由于您再次使用(in-package :amir),因此该包中将评估以下形式,因此您可以使用其中定义的所有功能。要检查导出的定义,应切换到其他程序包。

让我们尝试标准软件包CL-USER

AMIR> (in-package :cl-user)
#<Package "COMMON-LISP-USER">
CL-USER> (say-hi)
Undefined function SAY-HI called with arguments ("world")  ; as expected, but...
CL-USER> (say-hi-to "world")
Undefined function SAY-HI-TO called with arguments ("world") ; ops!!
CL-USER> (amir:say-hi-to "world)
"Hello world from COMMON-LISP-USER!"
CL-USER> (amir:say-hi)
Reader error: No external symbol named "SAY-HI" in package #<Package "THEHILARIOUSPACKAGEOFAMIRTEYMURI"> .

原因是导出符号并不意味着我们可以在不限定其包的情况下使用它。但是,如您所见,只有从包装中导出的符号才能与“:”一起使用。如果要使用不带软件包名称的符号作为前缀,则必须先导入它。

所以,让我们重新开始。

CL-USER> (defpackage :another-package (:use :amir))
#<Package "ANOTHER-PACKAGE">
CL-USER> (in-package :another-package)
#<Package "ANOTHER-PACKAGE">
ANOTHER-PACKAGE> (say-hi-to "world")
"Hello world from ANOTHER-PACKAGE!"
ANOTHER-PACKAGE> (say-hi)
Undefined function SAY-HI called with arguments ()

ANOTHER-PACKAGE内部,您现在可以无限制地使用导出的符号。

通常,在Common Lisp中,在包中导出和导入符号不是那么直观,可以在其他答案中引用的链接中找到对包的所有复杂性的良好描述。

答案 1 :(得分:1)

在不更改当前软件包的情况下检查差异。您将找到更多信息,例如here