我已经定义了一个类似于以下的程序包:
(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”也被导出?
答案 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