You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Lisp中when语句内调用make-instance创建Thing实例报错排查

解决Common Lisp中make-instance在方法内创建实例时的槽未绑定错误

问题现象

在SBCL和CLISP环境运行代码时,触发错误:The slot COMMON-LISP-USER::NAME is unbound in the object #<THING {1002B830F3}>。手动创建名为"ash"的Thing实例可成功,但在burn方法的when条件块内调用make-instance创建该实例时失败。

问题原因

错误根源在Thing类的initialize-instance :around方法中:调用call-next-method时,错误地将实例obj作为第一个参数传入。call-next-method在:around方法中会自动使用当前实例和原始参数(除非显式指定),额外传入的obj会被当作初始化参数的一部分,导致:name参数被错位处理,最终实例的name槽未被正确绑定。

修复方案

修改initialize-instance :around方法,移除call-next-method的第一个obj参数,直接将过滤后的初始化参数传递给call-next-method即可。

修复后的完整代码

(defclass thing ()
  ((name :initarg :name :accessor thing-name)
   (properties :initform nil :accessor thing-properties)))

(defmethod initialize-instance :around ((obj thing) &rest initargs &key &allow-other-keys)
  (let* ((class (class-of obj)))
    (apply #'call-next-method  ; 移除多余的obj参数
           (loop for (key val) on initargs by #'cddr
                 when (member key '(name properties))  ; 仅允许指定的参数
                 append (list key val)))))

(defclass process () 
  ((name :initarg :name :accessor process-name)))

(defmethod burn ((proc process) (chair thing) (oxygen thing))
  (declare (ignore proc))
  (when (and (string= (thing-name chair) "chair")
             (string= (thing-name oxygen) "oxygen"))
    (make-instance 'thing :name "ash")))

;; 测试代码
(defparameter *chair* (make-instance 'thing :name "chair"))
(defparameter *oxygen* (make-instance 'thing :name "oxygen"))
(defparameter *burning* (make-instance 'process :name "burning"))

;; 执行燃烧操作
(defparameter *result* (burn *burning* *chair* *oxygen*))

;; 调试输出
(format t "Result: ~A" *result*)  ; 成功时会输出创建的"ash"实例

修复说明

修改后的initialize-instance :around方法会正确过滤初始化参数,并将其传递给默认的initialize-instance实现,确保:name参数被正常解析并绑定到实例槽中。无论手动创建实例还是在burn方法内部创建,都能完成正确的初始化。

内容的提问来源于stack exchange,提问作者nadirkazan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 15:53:11