在《实用通用Lisp》第17章“面向对象重构:类” 的“访问者函数”一节中,我发现很难理解SETF
的扩展方式。
以下是相关函数:
(defun (setf customer-name) (name account)
(setf (slot-value account 'customer-name) name))
bank-account
类定义:
(defclass bank-account ()
((customer-name
:initarg :customer-name
:initform (error "Must supply a customer name."))
(balance
:initarg :balance
:initform 0)
(account-number
:initform (incf *account-numbers*))
account-type))
我不理解的是:
在表达式
(setf (customer-name my-account) "Sally Sue")
中,(customer-name my-account)
返回一个可SETF的slot-value:类bank-account
中的customer-name
,然后SETF
用它来将值设置为"Sally Sue"吗?(setf (customer-name my-account) "Sally Sue")
实际上是否调用了上面的函数?如上所定义,
setf customer-name
是一个函数吗?在上面的函数中,
(setf customer-name)
和函数体中的'customer-name
是否引用同一内容?该部分说明:
第二个元素是一个符号,通常是用于访问SETF函数将要设置的位置的函数的名称。
如果是这样的话,为什么在函数定义内部使用
slot-value
函数,而不是可以用来访问位置的函数呢?
(setf (customer-name my-account) "Sally Sue")
调用了(setf-customer-name)
函数?但是该函数需要两个参数,而只传递了一个参数"Sally Sue"
。 - Bleeding Fingersaccount
是(setf customer-name)
的第一个参数,name
是第二个参数,它会起同样的作用吗?(看起来像某种黑魔法。) - Bleeding Fingerssetf
函数的语义在 HyperSpec 中定义。新值总是作为第一个参数传递给setf
函数。 - Tim