我想知道这是如何工作的:
(setf(车x)42)
(car x)是否返回setf的可赋值引用?或者只是宏观魔术?setf或汽车如何工作?
我知道通过引用传递将是函数式编程中的一个可怕的错误,但我想知道上面是如何完成的.
这是宏观的魔力.表单(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
Run Code Online (Sandbox Code Playgroud)
您还可以定义自己的扩展:
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
Run Code Online (Sandbox Code Playgroud)