setcar ¶ によるリスト要素の変更コンスセルのCARを変更するにはsetcarを使用します。リストに対して使用した場合、setcarはリストの1つの要素を別の要素に置き換えます。
この関数は、cons の新しい CAR として object を格納し、それまでの CAR を置き換えます。言い換えれば、cons の CAR スロットを object を指すように変更します。そして、値 object を返します。例えば:
(setq x (list 1 2))
⇒ (1 2)
(setcar x 4)
⇒ 4
x
⇒ (4 2)
コンスセルが複数のリストの共有構造の一部となっている場合、新しいCARをコンスに格納すると、これらの各リストの要素が1つずつ変更されます。以下に例を示します。
;; Create two lists that are partly shared.
(setq x1 (list 'a 'b 'c))
⇒ (a b c)
(setq x2 (cons 'z (cdr x1)))
⇒ (z b c)
;; Replace the CAR of a shared link. (setcar (cdr x1) 'foo) ⇒ foo x1 ; Both lists are changed. ⇒ (a foo c) x2 ⇒ (z foo c)
;; Replace the CAR of a link that is not shared. (setcar x1 'baz) ⇒ baz x1 ; Only one list is changed. ⇒ (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----
| | |
--------------