setf
能否与CLHS中的位置和 Norvig 的 PAIP 中的位置相同?
我试图弄清楚 Common Lisp 中的确切位置,但对我来说 HyperSpec 的解释
地点 n. 1. 适合用作一般参考的形式。2.这样一个地方[1]所指的概念位置。
只是帮助有限。
(我知道这不是真正适合的问题,但如果有人知道一篇解释可设置/地点/位置的好文章,我会很感激链接/参考)
setf
能否与CLHS中的位置和 Norvig 的 PAIP 中的位置相同?
我试图弄清楚 Common Lisp 中的确切位置,但对我来说 HyperSpec 的解释
地点 n. 1. 适合用作一般参考的形式。2.这样一个地方[1]所指的概念位置。
只是帮助有限。
(我知道这不是真正适合的问题,但如果有人知道一篇解释可设置/地点/位置的好文章,我会很感激链接/参考)
最初可变数据结构有一个 getter 和一个 setter。car
/rplaca
和cdr
/的示例rplacd
:
CL-USER 68 > (let ((a (cons 1 2)))
(print (list (car a) (cdr a)))
(rplaca a 'foo)
(rplacd a 'bar)
(print (list (car a) (cdr a)))
(values))
(1 2)
(FOO BAR)
在此示例中,getter 是car
和cdr
用于cons 单元格。设置器是rplaca
(replace car) 和rplacd
(replace cdr)。
每个可变数据结构都有这种情况,通常没有系统的方法可以通过知道 getter 的名称来猜测 setter 的名称。
因此,想法是有一个 getter 和 setter 的注册表。为 getter 注册一个 setter,用户只需知道 getter。setf
宏(以及其他类似的incf
,decf
以及用户定义的宏)然后为使用的 getter 查找 setter。
上面带有setf
宏的示例如下所示:
CL-USER 69 > (let ((a (cons 1 2)))
(print (list (car a) (cdr a)))
(setf (car a) 'foo)
(setf (cdr a) 'bar)
(print (list (car a) (cdr a)))
(values))
(1 2)
(FOO BAR)
如您所见,使用rplaca
andrplacd
已被setf
宏取代。
因此,一个地方基本上是一个注册表格,有一个设置者。为此使用了defsetf和define-setf-expander。
define-modify-macro用来定义一个宏,可以修改一个地方。
例如,我们可以定义一种方法来乘以一个地方的值,类似于incf
(增加一个地方)和decf
(减少一个地方)。
此功能很旧,最初使用field一词而不是place。因此,能够使用位置的宏以f(字段)结尾。
CL-USER 71 > (define-modify-macro multf (&rest args)
* "multiply")
MULTF
CL-USER 72 > (let ((a (cons 1 2)))
(print (list (car a) (cdr a)))
(multf (car a) 2)
(multf (cdr a) 4)
(print (list (car a) (cdr a)))
(values))
(1 2)
(2 8)