我希望创建一个源文件,其中所定义的大部分函数都是该源文件的本地函数。在C中,通过标记函数static来达到相同的目的;在C++中,也可以用namespace { ... }包围它们。我在Lisp中得到的印象是,包系统是合适的工具。然而,到目前为止,我的尝试并没有奏效。
这是我目前所拥有的,但是SBCL拒绝它的声明,声称global-fun是未定义的。显式地将其称为cl-user:global-fun,会产生类似的结果。我该怎么做?
(defun global-fun ()
(format t "global~%"))
(defpackage :local-package
(:use :common-lisp)
(:use :cl-user))
(in-package :local-package)
(defun local-fun ()
(global-fun)
(format t "local~%"))发布于 2018-10-13 23:31:49
你就快到了。你可以用Slime的自动完成来找出答案。
要么导出global-fun,要么用双冒号:(cl-user::global-fun)访问它。
与另一个global-package
(defpackage :global-package
(:use :common-lisp) ;; <-- can be :cl
;; (:use :cl-user) <-- not necessary
(:export :global-fun))
(in-package :global-package)
(defun global-fun () …)
(defpackage :local-package
(:use :cl
:global-defun)) ;; <-- one ":use" is possible
(in-package :local-package)
; etc发布于 2018-10-15 08:27:05
这里似乎有一些误解。
在通用Lisp中,没有所谓的“全局函数”。您首先在文件中定义的东西,global-fun在某些包中,很可能是cl-user包。
包和文件之间也没有直接的通信。您可以在单个文件中为不同的包定义东西,也可以在多个文件中为单个包定义东西。为了使事情清晰易懂,有一个非常明智的约定:总是使用in-package表单启动源文件(在某些样式中使用defpackage表单),并且永远不要在文件后面的某个地方放置另一个in-package。
当您编写没有包的符号时,例如somefun或myarray,它会被嵌入到当前包中(例如,一种幂等的注册)(参见下面的内容)。这与您当前是否定义或引用它是独立的,因为它是由读者在读取源代码表单时完成的。在以下两种形式中,名为foo的符号被嵌入到当前包中(这两种形式都会导致使用相同的符号):
(defun foo ()
…)
(foo)为了引用来自不同包的符号,您需要将包名作为前缀,以::作为分隔符,就像在my-package::foo中那样,但是这通常是一种代码气味,因为…
…您应该从您的包定义导出您的包的用户要使用的任何符号:
(defpackage my-package
(:use common-lisp)
(:export foo))您可以引用以单个冒号作为分隔符的另一个包中导出的符号,如my-package:foo中的那样,这是很好的样式。
现在,当前包只是变量*package*的值。如果您从REPL会话的角度来看它,这就是最近的in-package调用的论点。在整个文件编译的上下文中,它是在词汇上最接近前面的in-package表单的值。在文件中的单格式编译的上下文中,IDE将(无论如何,我已经看到)查找前面的in-package表单,即使它没有显式计算。在原始的Lisp映像中,起始包是common-lisp-user,它有一个昵称cl-user。
https://stackoverflow.com/questions/52798134
复制相似问题