gpt4 book ai didi

oop - 为什么泛型函数与访问函数 lisp 不同

转载 作者:太空宇宙 更新时间:2023-11-03 18:51:32 24 4
gpt4 key购买 nike

根据我所读的内容,我了解到 CLOS 中的访问器函数允许程序员获取和设置变量,并且它生成一个通用函数的名称,该函数提供给您需要定义不同方法的访问器。但我想知道的是,为什么泛型函数的工作方式与访问函数不同?

例如

 (defclass animal ()
((sound
:initarg :sound
:initform "no sound"
:accessor make-sound)))

我可以定义

(defmethod (setf make-sound) ((the-animal animal) value)
(setf (slot-value the-animal 'sound) value))

但是如果我要拿走访问器并添加进去

(defgeneric (setf make-sound) (the-animal value))

然后在执行下面的代码后我得到一个错误。

(setf (make-sound dog) "bark")

除非我重新定义泛型函数和方法如下

(defgeneric (setf make-sound) (value the-animal))

(defmethod (setf make-sound) (value (the-animal animal))
(setf (slot-value the-animal 'sound) value))

或执行

(setf (make-sound "bark") dog) ;this also works with the accessor

我的问题是为什么会这样?为什么我不能用泛型函数实现相同的结果?

最佳答案

A defmethod如果没有通用函数,表单会创建一个通用函数

CL-USER 7 > (defclass animal ()
((sound
:initarg :sound
:initform "no sound")))
#<STANDARD-CLASS ANIMAL 40200ED09B>

记住:新值首先出现在 SETF 函数中。这是由 Common Lisp 标准定义的。

CL-USER 8 > (defmethod (setf make-sound) (value (the-animal animal))
(setf (slot-value the-animal 'sound) value))
#<STANDARD-METHOD (SETF MAKE-SOUND) NIL (T ANIMAL) 40200F098B>

CL-USER 9 > (let ((dog (make-instance 'animal)))
(setf (make-sound dog) "bark")
dog)
#<ANIMAL 402002187B>

CL-USER 10 > (slot-value * 'sound)
"bark"

似乎有效。

defclass :accessor 插槽选项定义它定义了一个读取器方法以及一个相应的 setf 方法,其中包含正确的参数列表:首先是新值,然后是该类的实例。

关于oop - 为什么泛型函数与访问函数 lisp 不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51561275/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com