使用自定义函数getter作为setf的setf

时间:2013-12-01 10:25:52

标签: lisp common-lisp

我认为从这段代码中可以看出我正在尝试做什么,即将'blue更改为'purple

CL-USER> (defparameter myassoc '((color red blue) (shape circle square)))
MYASSOC
CL-USER> myassoc
((COLOR RED BLUE) (SHAPE CIRCLE SQUARE))
CL-USER> (defun getsecondof (assoc) (second (rest (assoc assoc myassoc))))
GETSECONDOF
CL-USER> (getsecondof 'color)
BLUE
CL-USER> (setf (getsecondof 'color) 'purple)
; in: SETF (GETSECONDOF 'COLOR)
;     (FUNCALL #'(SETF GETSECONDOF) #:NEW954 'COLOR)
; ==>
;   (SB-C::%FUNCALL #'(SETF GETSECONDOF) #:NEW954 'COLOR)
; 
; caught STYLE-WARNING:
;   undefined function: (SETF GETSECONDOF)
; 

现在,如果不使用我自己的函数getsecondofsetf,而是传递一个内置的CL表达式来提取我想要更改的位置,它就可以了。

是否可以将自定义getter用作setf的设置者?

2 个答案:

答案 0 :(得分:3)

答案 1 :(得分:3)

您需要为其定义setf

(defun (setf getsecondof) (assoc value)
  (setf (caddr (assoc assoc myassoc)) value)) ; (caddr x) == (second (rest x))

(setf (getsecondof 'color) 'purple) ; ==> PURPLE
(getsecondof 'color) ; ==> PURPLE