为什么泛型函数与访问函数 lisp 不同
Why aren't generic functions the same as accessor functions lisp
根据我所读的内容,我了解到 CLOS 中的访问器函数允许程序员获取和设置变量,并且它生成一个通用函数的名称,该函数提供给您需要定义不同的访问器methods.But 我想知道的是为什么泛型函数的工作方式与访问函数不同?
例如
(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
我的问题是为什么会这样?为什么我不能用泛型函数实现相同的结果?
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
插槽选项定义了它定义了一个reader方法以及一个相应的setf方法,并带有正确的参数列表:首先是新值,然后是 class.
的实例
根据我所读的内容,我了解到 CLOS 中的访问器函数允许程序员获取和设置变量,并且它生成一个通用函数的名称,该函数提供给您需要定义不同的访问器methods.But 我想知道的是为什么泛型函数的工作方式与访问函数不同?
例如
(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
我的问题是为什么会这样?为什么我不能用泛型函数实现相同的结果?
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
插槽选项定义了它定义了一个reader方法以及一个相应的setf方法,并带有正确的参数列表:首先是新值,然后是 class.