例如,我有这个包定义,它遮蔽了COMMON-LISP:LISTEN:
(defpackage :shadows
(:use :common-lisp)
(:shadow #:listen)
(:export #:listen))然后我想使用另一个包中的包,比如
(defpackage :light
(:use :common-lisp
:shadows))如果我在使用包时不能实际覆盖Common Lisp符号,那么卷影的用途是什么?
发布于 2017-06-17 03:33:05
简单
defpackage的:shadow参数会影响包shadows的定义,而不会影响以后在light中使用shadows。
您需要使用shadowing-import
(defpackage #:shadows
(:use #:common-lisp)
(:shadow #:listen)
(:export #:listen))
(defpackage #:light
(:shadowing-import-from #:shadows #:listen)
(:use #:common-lisp #:shadows))
(eq 'light::listen 'shadows:listen)
==> T
(describe 'light::listen)
==>
SHADOWS:LISTEN is the symbol SHADOWS:LISTEN, lies in #<PACKAGE SHADOWS>,
is accessible in 2 packages LIGHT, SHADOWS.
#<PACKAGE SHADOWS> is the package named SHADOWS.
It imports the external symbols of 1 package COMMON-LISP and
exports 1 symbol to 1 package LIGHT.散装
如果需要进行批量跟踪,则需要使用单独的函数(make-package、import、export、shadow、use-package):
(defparameter *my-shadow-list* '(#:car #:cdr))
(make-package '#:my-package :use nil)
(import *my-shadow-list* '#:my-package)
(export *my-shadow-list* '#:my-package)
(shadow *my-shadow-list* '#:my-package)
(use-package '#:cl '#:my-package)
(make-package '#:my-user)
(shadowing-import *my-shadow-list* '#:my-user)
(use-package '(#:cl #:my-package) '#:my-user)
(describe 'my-user::car)
==>
MY-PACKAGE:CAR is the symbol MY-PACKAGE:CAR, lies in #<PACKAGE MY-PACKAGE>,
is accessible in 2 packages MY-PACKAGE, MY-USER.
#<PACKAGE MY-PACKAGE> is the package named MY-PACKAGE.
It imports the external symbols of 1 package COMMON-LISP and
exports 2 symbols to 1 package MY-USER.你可能会发现macroexpand-1在判断如何找到你需要去的地方时很有用:
(macroexpand-1 '(defpackage #:light
(:shadowing-import-from #:shadows #:listen)
(:use #:common-lisp #:shadows)))
==>
(EVAL-WHEN (:COMPILE-TOPLEVEL :LOAD-TOPLEVEL :EXECUTE)
(SYSTEM::%IN-PACKAGE "LIGHT" :NICKNAMES 'NIL :USE 'NIL :CASE-SENSITIVE NIL
:CASE-INVERTED NIL)
(SYSTEM::SHADOWING-IMPORT-CERROR "LISTEN" "SHADOWS" NIL "LIGHT")
(USE-PACKAGE '("COMMON-LISP" "SHADOWS") "LIGHT") (FIND-PACKAGE "LIGHT")) ;
TPS。隐藏ANSI CL标准名称对于代码的可读性来说不是一个很好的主意。
发布于 2017-06-17 04:13:08
好的,实际上有一个简单的方法可以做到这一点。
在我的多阴影包中,我导出了一个shadowing-import-from函数。它看起来是这样的:
(defun shadowing-import-from ()
`(:shadowing-import-from :many-shadows
,@(package-shadowing-symbols :many-shadows)))然后,在轻量级的defpackage中,我读到了-EVAL it:
(defpackage :light
(:use :common-lisp
:many-shadows)
#.(many-shadows:shadowing-import-from))所以很明显,某些东西被阴影了,我想优先使用来自多个阴影的符号。而且它足够短,可以被记录下来,并实际使用。
谢谢你@sds给我指给我:shadowing-import-from。
发布于 2017-06-20 21:50:33
如果我在使用包时实际上不能覆盖Common Lisp符号,那么卷影的用途是什么?
具有阴影符号列表的包的目的是解决由该包使用的包引起的冲突。阴影对导出的任何内容都没有影响。
当一个包使用其他包时,当两个或多个使用过的包以相同的名称导出一个符号时,可能会出现冲突。同样,在使用的包和本地包中的符号之间也可能出现冲突。这些冲突被视为错误。在逐个符号的基础上,阴影消除了这些冲突。出现在包中的符号被添加到其隐藏符号列表中。然后,任何冲突都会以有利于该符号的方式静默解决。
作为一个阴影符号并不会给一个符号赋予任何特殊的能力,当它被认为是从外部的包装,在那里它的地位。
对于每个包,我们必须单独安排“可见性堆栈”,如果需要的话,包括它自己的阴影符号。
https://stackoverflow.com/questions/44596132
复制相似问题