在Common Lisp中定义setf-expanders

Joh*_*han 13 common-lisp setf

事情就是这样:我没有"获得"setf-expanders,并希望了解它们是如何工作的.

我需要了解它们是如何工作的,因为我遇到了一个问题,这似乎是为什么你应该学习setf-expanders的典型例子,问题如下:

(defparameter some-array (make-array 10))

(defun arr-index (index-string)
  (aref some-array (parse-integer index-string))

(setf (arr-index "2") 7) ;; Error: undefined function (setf arr-index)
Run Code Online (Sandbox Code Playgroud)

如何为ARR-INDEX编写合适的setf-expander?

Rai*_*wig 19

(defun (setf arr-index) (new-value index-string)
  (setf (aref some-array (parse-integer index-string))
        new-value))
Run Code Online (Sandbox Code Playgroud)

在Common Lisp中,函数名称不仅可以是符号,还可以是包含SETF第一个符号的两个符号的列表.往上看.DEFUN因此可以定义SETF功能.该函数的名称是(setf arr-index).

SETF函数可以被用在地方形式:CLHS:其它化合物形式地方.

新值是第一个参数.

CL-USER 15 > some-array
#(NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL)

CL-USER 16 > (setf (arr-index "2") 7)
7

CL-USER 17 > some-array
#(NIL NIL 7 NIL NIL NIL NIL NIL NIL NIL)
Run Code Online (Sandbox Code Playgroud)

  • 我在 CLHS 中找不到这个,它在哪里? (2认同)
  • `#'(setf arr-index)` 现在是一个可以调用的函数。这就是 setf 宏扩展的内容,即`(funcall #'(setf arr-index) new-value index-string)`。 (2认同)

Tim*_*Tim 6

Rainer 的回答恰到好处。在 ANSI Common Lisp 之前,有必要defsetf为简单的地方定义一个扩展器,这些地方可以通过简单的函数调用来设置。setf(setf arr-index)CLOS这样的功能进入语言并简化了很多事情。特别是,setf函数可以是通用的。