5.6.2 修改列表的 CDR

修改 CDR 最底层的原语是 setcdr

Function: setcdr cons object

该函数将 object 存为 cons 的新 CDR,替换掉它原先的 CDR。换句话说,它修改 consCDR 槽位,使其指向 object。函数返回值为 object

下面是一个用另一个列表替换列表 CDR 的示例。列表中除第一个元素外的所有元素都被移除,替换为另一组元素。第一个元素保持不变,因为它存放在列表的 CDR 中,不会通过 CDR 被访问到。

(setq x (list 1 2 3))
     ⇒ (1 2 3)
(setcdr x '(4))
     ⇒ (4)
x
     ⇒ (1 4)

通过修改列表中 cons 单元的 CDR,可以从列表中间删除元素。例如,我们通过修改第一个 cons 单元的 CDR,从列表 (a b c) 中删除第二个元素 b

(setq x1 (list 'a 'b 'c))
     ⇒ (a b c)
(setcdr x1 (cdr (cdr x1)))
     ⇒ (c)
x1
     ⇒ (a c)

这是方框表示法下的结果:

                   --------------------
                  |                    |
 --------------   |   --------------   |    --------------
| car   | cdr  |  |  | car   | cdr  |   -->| car   | cdr  |
|   a   |   o-----   |   b   |   o-------->|   c   |  nil |
|       |      |     |       |      |      |       |      |
 --------------       --------------        --------------

原先存放元素 b 的第二个 cons 单元仍然存在,它的 CDR 仍然是 b,但它不再属于这个列表。

通过修改 CDR 来插入新元素同样简单:

(setq x1 (list 'a 'b 'c))
     ⇒ (a b c)
(setcdr x1 (cons 'd (cdr x1)))
     ⇒ (d b c)
x1
     ⇒ (a d b c)

这是方框表示法下的结果:

 --------------        -------------       -------------
| car  | cdr   |      | car  | cdr  |     | car  | cdr  |
|   a  |   o   |   -->|   b  |   o------->|   c  |  nil |
|      |   |   |  |   |      |      |     |      |      |
 --------- | --   |    -------------       -------------
           |      |
     -----         --------
    |                      |
    |    ---------------   |
    |   | car   | cdr   |  |
     -->|   d   |   o------
        |       |       |
         ---------------

emacs

Emacs

org-mode

Orgmode

Donations

打赏

Copyright

© 2025 Jasper Hsu

Creative Commons

Creative Commons

Attribute

Attribute

Noncommercial

Noncommercial

Share Alike

Share Alike