常见的lisp defclass自定义宏中的make-instance用法

时间:2014-03-22 21:40:06

标签: macros common-lisp sbcl clos

我定义了一个创建新类的宏,然后定义了一个创建新定义类的实例的常量:

(defmacro my-class (name inst)
  `(progn
     (defclass ,name nil nil)
     (defconstant ,inst (make-instance ',name)))))

这似乎适用于REPL

(my-class x1025 y1025)

但是在文件中编译它时不起作用:

There is no class named COMMON-LISP-USER::X1025.
   [Condition of type SIMPLE-ERROR]

Restarts:
  0: [ABORT] Abort compilation.
  1: [*ABORT] Return to SLIME's top level.
  2: [REMOVE-FD-HANDLER] Remove #<SB-IMPL::HANDLER INPUT on descriptor 8: #<CLOSURE (LABELS SWANK-BACKEND::RUN :IN SWANK-BACKEND:ADD-FD-HANDLER) {13228535}>>
  3: [ABORT] Exit debugger, returning to top level.

Backtrace:
  0: (SB-PCL::FIND-CLASS-FROM-CELL X1025 NIL T)
  1: ((:METHOD MAKE-INSTANCE (SYMBOL)) X1025) [fast-method]
  2: (SB-INT:SIMPLE-EVAL-IN-LEXENV (MAKE-INSTANCE (QUOTE X1025)) #<NULL-LEXENV>)

1 个答案:

答案 0 :(得分:3)

在编译期间可能无法以Lisp可以创建实例的方式知道该类。标准说在编译期间应该知道类 - 但是在实际执行DEFCLASS表单之前不能创建实例。

DEFCONSTANT可能会在编译期间评估MAKE-INSTANCE表单。正如你在回溯中看到的那样,SBCL实际上试图调用MAKE-INSTANCE

您需要在编译期间使类完全可用。请参阅EVAL-WHEN或将类声明放在另一个文件中,您需要先加载它。