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

Lisp CLOS中如何让类的setter自动更新另一个槽位?

CLOS中更新尺寸自动同步体积的解决方案

方案一:动态计算体积(推荐)

不需要将volume作为存储槽,而是通过方法实时计算长宽高的乘积,确保每次访问都能得到最新值:

修改类定义(修正了原代码中breath的拼写错误为breadth):

(defclass box ()
  ((length :accessor box-length :initform 0 :initarg :bxl)
   (breadth :accessor box-breadth :initform 0 :initarg :bxb)
   (height :accessor box-height :initform 0 :initarg :bxh)))

定义volume方法:

(defmethod volume ((b box))
  (* (box-length b) (box-breadth b) (box-height b)))

简化构造函数,无需手动传入体积:

(defun make-box (l b h)
  (make-instance 'box :bxl l :bxb b :bxh h))

测试验证:

(defparameter my-box (make-box 4 3 2))
(volume my-box) ; 返回24
(setf (box-height my-box) 5)
(volume my-box) ; 返回60

这种方式消除了冗余存储,从根本上避免数据不一致,更贴合CLOS的设计思路。

方案二:保留体积槽,重写setf方法

若必须存储volume值,可重写尺寸属性的setf方法,在更新尺寸后自动同步体积:

类定义(保留volume槽,移除手动传入的:initarg):

(defclass box ()
  ((length :accessor box-length :initform 0 :initarg :bxl)
   (breadth :accessor box-breadth :initform 0 :initarg :bxb)
   (height :accessor box-height :initform 0 :initarg :bxh)
   (volume :reader volume :initform 0)))

定义体积更新的辅助方法:

(defmethod update-volume ((b box))
  (setf (slot-value b 'volume)
        (* (box-length b) (box-breadth b) (box-height b))))

重写各尺寸的setf方法:

(defmethod (setf box-length) (new-val (b box))
  (setf (slot-value b 'length) new-val)
  (update-volume b))

(defmethod (setf box-breadth) (new-val (b box))
  (setf (slot-value b 'breadth) new-val)
  (update-volume b))

(defmethod (setf box-height) (new-val (b box))
  (setf (slot-value b 'height) new-val)
  (update-volume b))

构造函数初始化时同步体积:

(defun make-box (l b h)
  (let ((box (make-instance 'box :bxl l :bxb b :bxh h)))
    (update-volume box)
    box))

测试验证:

(defparameter my-box (make-box 4 3 2))
(volume my-box) ; 返回24
(setf (box-height my-box) 5)
(volume my-box) ; 返回60

这种方式需要维护多个setf方法,适合有特定存储需求的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 20:23:28