setcar
によるリスト要素の変更 ¶コンスセルのCARの変更はsetcar
で行ないます。リストにたいして使用するとsetcar
はリストの1つの要素を別の要素に置き換えます。
この関数は以前のCARを置き換えて、consの新しいCARにobjectを格納する。言い換えると、この関数はconsのCARスロットをobjectを参照するように変更する。この関数は値objectをリターンする。たとえば:
(setq x (list 1 2)) ⇒ (1 2)
(setcar x 4) ⇒ 4
x ⇒ (4 2)
コンスセルが複数のリストを共有する構造の一部なら、コンスに新しいCARを格納することにより、これら共有されたリストの各1つの要素を変更します。以下は例です:
;; 部分的に共有された2つのリストを作成
(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 ; 1つのリストだけが変更された ⇒ (baz foo c) x2 ⇒ (z foo c)
なぜb
を置き換えると両方が変更されるのかを説明するために、変数x1
とx2
の2つのリストによる共有構造を視覚化してみましょう:
--- --- --- --- --- --- 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---- | | | --------------