【问题标题】:unexpected inheritance of slot (values) using errors使用错误意外继承插槽(值)
【发布时间】:2013-04-10 15:45:29
【问题描述】:
(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

这是非常出乎意料的。 我犯了什么错误?

【问题讨论】:

    标签: namespaces package common-lisp


    【解决方案1】:

    如果你使用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::NAMEPACKAGELOSER::NAME

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

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

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

    您需要注意什么?

    • 有一个自定义打印机很好,但使用DESCRIBE 进行调试
    • 包是符号的命名空间。它们不是类、槽、函数等概念的模块。
    • CL 带有许多符号。如果您的包使用包CL,那么它具有所有这些符号。是否将它们用于函数名、变量、类名、槽名……都没有关系。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-23
      • 2018-02-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-15
      • 1970-01-01
      相关资源
      最近更新 更多