次: Setcdr, 前: Modifying Lists, 上: Modifying Lists
setcarによるリスト要素の変更コンスセルのcarを変更するには、setcarを使います。
リストに対して使用すると、
setcarはリストの1つの要素を別の要素に置き換えます。
この関数は、consの新たなcarとしてobjectを格納し、 以前のcarを置き換える。 いいかえれば、consのcarスロットがobjectを指すように変更する。 この関数は値objectを返す。 たとえば、つぎのようになる。
(setq x '(1 2)) => (1 2) (setcar x 4) => 4 x => (4 2)
コンスセルが複数のリストの共有構造の一部であるときには、 コンスセルに新たなcarを格納すると、 そのような各リストの1つの要素を変更することになります。
;; 共有部分がある2つのリストを作る
(setq x1 '(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 ; 1つのリストだけが変更されている
=> (baz foo c)
x2
=> (z foo c)
変数x1とx2に入っている共有部分を持つ2つのリストを図示すると
つぎのようになります。
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----
| | |
--------------