在Lisp中为类定义自定义setf

4
假设我有一个名为board的类:
(defclass board ()
 ((blocker    :accessor blocker    :initarg :blocker    :initform  0))

根据这本书籍,我可以定义一个自定义的setf来阻止器的操作:
(defmethod (setf blocker) (new-blocker (b board))
  (setf (slot-value b 'blocker) new-blocker))

然而,Steel Bank Common Lisp会说函数未定义,即使我已经评估了它。有人知道这里出了什么问题吗?

4
请注意:由于已经有了 :accessor 关键字,您不需要再定义 (setf blocker)。 - GoZoner
2个回答

1

看起来没问题。请注意,您正在重新定义已经创建的setf方法,通过指定:accessor blocker。SBCL会对此发出style-warning警告。

您的错误可能在其他地方。也许您在不同的包中?尝试展示您在IDE中编译和加载这些表单以及尝试运行该方法调用的步骤。


我尝试使用(fboundp 'setf-blocker)来检查setf-blocker是否已定义,但它返回了nil。而当我尝试自己定义它时,它仍然抱怨该函数未定义。 - Mark
在我的环境中,使用最新的SBCL和OS X可以工作。你的defclass表单缺少一个闭合括号,这是问题吗?不过这是一本好书;还可以看看《元对象协议的艺术》。 - Clayton Stanley
@Mark:那个函数不是叫做setf-blocker,而是(setf blocker)。请展示你正在尝试评估的代码。 - Svante

0

在定义任何方法之前,您必须先声明一个通用函数。

(defgeneric (setf blocker) (new-blocker board))

在《实用通用Lisp》中查看this章节以获取示例。

1
不正确。如果不存在通用函数,则会为您创建一个。有关详细信息,请参见http://l1sp.org/7.6.2。 - Xach
哦,你说得对,SBCL只会发出一个STYLE-WARNING。顺便说一下,你的链接无效。(7.6.2 - Daimrod

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接