5.6.1 使用 setcar 修改列表元素

修改一个 cons 单元的 CAR 可以使用 setcar。当作用于列表时,setcar 会用另一个元素替换列表中的某个元素。

Function: setcar cons object

本函数将 object 存为 cons 的新 CAR,替换掉它之前的 CAR。换句话说,它修改 consCAR 槽,使其指向 object。函数返回值为 object。 示例:

(setq x (list 1 2))
     ⇒ (1 2)
(setcar x 4)
     ⇒ 4
x
     ⇒ (4 2)

当一个 cons 单元是多个列表共享结构的一部分时,给该 cons 设置新的 CAR 会同时改变这些列表的对应元素。示例如下:

;; 创建两个存在部分共享的列表
(setq x1 (list 'a 'b 'c))
     ⇒ (a b c)
(setq x2 (cons 'z (cdr x1)))
     ⇒ (z b c)

;; 替换共享节点的 CAR
(setcar (cdr x1) 'foo)
     ⇒ foo
x1                           ; 两个列表都被改变
     ⇒ (a foo c)
x2
     ⇒ (z foo c)

;; 替换非共享节点的 CAR
(setcar x1 'baz)
     ⇒ baz
x1                           ; 只有一个列表被改变
     ⇒ (baz foo c)
x2
     ⇒ (z foo c)

下面是变量 x1x2 中两个列表共享结构的图示,这也解释了为什么替换 b 会同时改变两个列表:

        --- ---        --- ---      --- ---
x1---> |   |   |----> |   |   |--> |   |   |--> nil
        --- ---        --- ---      --- ---
         |        -->   |            |
         |       |      |            |
          --> a  |       --> b        --> c
                 |
       --- ---   |
x2--> |   |   |--
       --- ---
        |
        |
         --> z

下面是另一种方框图示形式,表示同样的关系:

x1:
 --------------       --------------       --------------
| car   | cdr  |     | car   | cdr  |     | car   | cdr  |
|   a   |   o------->|   b   |   o------->|   c   |  nil |
|       |      |  -->|       |      |     |       |      |
 --------------  |    --------------       --------------
                 |
x2:              |
 --------------  |
| car   | cdr  | |
|   z   |   o----
|       |      |
 --------------

emacs

Emacs

org-mode

Orgmode

Donations

打赏

Copyright

© 2025 Jasper Hsu

Creative Commons

Creative Commons

Attribute

Attribute

Noncommercial

Noncommercial

Share Alike

Share Alike