关于“defun”中的“setf”?

11

我不完全理解在defun中使用setf的用法:

(defun cookies-out* (&optional (reply *reply*))
"Returns an alist of the outgoing cookies associated with the REPLY object REPLY."
    (cookies-out reply))

(defun (setf cookies-out*) (new-value &optional (reply *reply*))
"Sets the alist of the outgoing cookies associated with the REPLY object REPLY."
    (setf (cookies-out reply) new-value))

我想它重新定义了函数 #'cookies-out*,对吗?如果是这样的话,那么#'cookies-out*将会是一个多态函数。


7
搜索“setf扩展器”,并查看此链接 - Daimrod
1个回答

15

你的代码片段没有重新定义任何函数。它本质上是扩展了Common Lisp的赋值能力——这是该语言的一个不错的特性。如果有人尝试执行(setf (cookies-out* ...) ...),那么你后面的代码片段将被用来执行该赋值操作。

你问题的评论者已经提到了这些“setf扩展器”,为了进一步阐述,你可能会发现从CLHS中阅读以下内容很有用。请注意,你的示例使用了(defun (setf ...) ...)形式,因此前两个链接适用。

DEFUN允许您定义一个函数,该函数将在SETF运行时执行。

DEFSETF 允许您为任务命名一个 函数(使用短形式),或者定义一个 (使用长形式),该宏将在 SETF 中被展开,对于后一种情况,您通常需要小心地使用 PROGN。

当 DEFSETF 的长形式不足以满足需求时,可以使用 DEFINE-SETF-EXPANDER,尽管我从未有过使用它的原因。有关此主题的一些有用信息,请参见此 comp.lang.lisp 线程:https://groups.google.com/forum/#!searchin/comp.lang.lisp/difference$20between$20defsetf$20defun$20setf/comp.lang.lisp/5x3fjzMQ6Q0/_y8Q-P-SVPQJ

从我的个人经验来看,编写自己的 SETF 展开器的需求很少,因为我越来越多地以“功能”风格编写代码。也就是说,在访问复杂结构以进行修改时,这种技术通常是非常方便的... 至少在我了解到函数镜头是否是可行/值得选择之前。


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