2011-04-12 68 views

回答

9

这是宏观魔法。表单(setf的地方值)不过是一个专门的宏观扩展。例如,(setf(car x)42)将被翻译成如下形式:(rplaca x 42)。

你可以看到你的Lisp实现是如何扩展使用MACROEXPAND一个SETF形式,像这样(我的例子是使用SBCL,其他实施方式可以有完全不同的扩展):

CL-USER> (macroexpand '(setf (aref foo 10) 1234)) 
(SB-KERNEL:%ASET FOO 10 1234) 
T 

您也可以定义自己的扩展:

CL-USER> (defvar *value* 0) 
*VALUE* 
CL-USER> (defun get-value() *value*) 
GET-VALUE 
CL-USER> (defun (setf get-value) (x) (setq *value* x)) 
(SETF GET-VALUE) 
CL-USER> (setf (get-value) 42) 
42 
CL-USER> (get-value) 
42 
CL-USER> (macroexpand '(setf (get-value) 23)) 
(LET*() 
    (MULTIPLE-VALUE-BIND (#:NEW1058) 23 (FUNCALL #'(SETF GET-VALUE) #:NEW1058))) 
T 
6

In Common Lisp,这是一个的地方。一个地方是一个定义了setf扩展器的表单。这就像一个广义的参考。请致电Hyperspec

相关问题