当前位置 : 主页 > 手机开发 > 其它 >

名称空间 – 使用错误意外继承槽(值)

来源:互联网 收集:自由互联 发布时间:2021-06-19
(defpackage :winner (:use :cl) (:export e1))(in-package :winner)(define-condition e1 () ((name :initform "e1" :reader name) (package :initform "winner" :reader related-package)))(defmethod print-object ((err e1) stream) (FORMAT stream "~a~%
(defpackage :winner
  (:use :cl)
  (:export e1))

(in-package :winner)

(define-condition e1 ()
  ((name
    :initform "e1"
    :reader name)
   (package 
    :initform "winner"
    :reader related-package)))

(defmethod print-object ((err e1) stream)
  (FORMAT stream "~a~%~a~%" (name err) (related-package err)))


(defpackage :loser
  (:use :cl :winner)
  (:export e2))

(in-package :loser)

(define-condition e2 (e1)
  ((name
    :initform "e2")
   (package
    :initform "loser")))

我现在期待:

(make-instance 'e1)
e1
winner

(make-instance 'e2)
e2
loser

但我得到了

(make-instance 'winner:e1)
e1
winner

(make-instance 'loser:e2)
e1
loser

这是非常意外的.
我犯了什么错误?

如果您使用DESCRIBE,这相对容易看出.

? (make-instance 'loser:e2)
e1
loser

? (describe *)
e1
loser

Class: #<STANDARD-CLASS LOSER:E2>
Wrapper: #<CCL::CLASS-WRAPPER LOSER:E2 #x302000ECE15D>
Instance slots
WINNER::NAME: "e1"
PACKAGE: "loser"
LOSER::NAME: "e2"

你看到的是该对象有三个(!)插槽:WINNER :: NAME,PACKAGE和LOSER :: NAME.

这是为什么? PACKAGE是包CL中的符号(PACKAGE是一个系统类,一个类型,在Common Lisp中).由于您的包都使用CL,因此两者都具有相同的符号PACKAGE,因此只有一个名为CL的插槽:PACKAGE.

NAME是每个包裹的本地符号.每个包都有自己的符号名称.因此每个对象有两个不同的插槽WINNER :: NAME和LOSER :: NAME.

由于您的打印机功能仅读取WINNER :: NAME插槽,因此您只能获取其内容.

你需要记住什么?

>拥有自定义打印机很好,但使用DESCRIBE进行调试>包是符号的名称空间.它们不是类,槽,函数等概念的模块.>包CL带有许多符号.如果您的包使用包CL,那么它具有所有这些符号.是否将它们用于函数名,变量,类名,插槽名,……无关紧要.

网友评论