我正在尝试在(SBCL)Common Lisp中编写一个小游戏,使用Quickload和ASDF来定义和管理依赖项。它使用CLOS,因此我在project
中有一个名为classes
的目录,其中有一个文件locatable.cl
。
LOCATABLE类的defclass
形式需要一个LOCATOR参数,所以我有一行:
:initform (error "Must supply a locator parameter for this class.")
每当我尝试加载此文件或quickload
系统时,我都会收到上面的错误(“必须为此类提供定位器参数”)。因为我正在尝试定义一个系统而不是创建该类的任何实例,所以我不明白为什么我会这样做。如果我注释掉错误行,那么一切都很好,但是我被引导相信我拥有它的方式是需要:initval
插槽的标准方法。
如何定义这样的东西,以便您可以加载文件/制作系统定义而不会实际发出错误信号?
这是班级 -
(defclass locatable ()
((zone
:accessor zone
:initform nil)
(locator
:initarg :locator
:initform (error "Must supply a locator parameter for this class.")
:allocation :class
:accessor locator)))
更新:我在REPL输入表单并得到了同样的错误。出于好奇心的缘故,我再次输入两次,首先是:initform ""
,然后是错误表单。它接受了第一种形式,并没有抱怨第二种形式,所以这个问题似乎没有发生在 re -definition。
答案 0 :(得分:1)
(defclass locatable ()
((zone
:accessor zone
:initform nil)
(locator
:initarg :locator
:initform (error "Must supply a locator parameter for this class.")
:allocation :class
:accessor locator)))
班级locator
在班级中共享。它将以某种方式分配给类对象。 DEFCLASS
表单创建此类对象。因此,在创建和初始化类对象时,通常会初始化插槽locator
。在创建该类的第一个实例之前的方式。
LispWorks Backtrace
CL-USER 50 : 1 > :b
Call to CLOS::CLASS-REDEFINITION-LOCK-DEBUGGER-WRAPPER
Call to INVOKE-DEBUGGER
Call to ERROR
Call to (METHOD CLOS::COMPUTE-CLASS-SLOT-CONSES (STANDARD-CLASS))
Call to (METHOD SHARED-INITIALIZE :AFTER (STANDARD-CLASS T)) ; <--
Call to CLOS::ENSURE-CLASS-USING-CLASS-INTERNAL
Call to (METHOD CLOS:ENSURE-CLASS-USING-CLASS (CLASS T))
Call to CLOS::ENSURE-CLASS-WITHOUT-LOD
Call to LET
Call to LET
Call to EVAL
Call to CAPI::CAPI-TOP-LEVEL-FUNCTION
Call to CAPI::INTERACTIVE-PANE-TOP-LOOP
Call to MP::PROCESS-SG-FUNCTION
如您所见,在类对象上调用SHARED-INITIALIZE
,然后初始化共享槽。
我也不认为这样调用error
应该在用户代码中完成。您可能会找到一种更好的方法来检查缺少的initargs。