15.3 Изменение структуры списка

Для изменения структуры уже имеющегося списка могут использоваться функции rplaca и rplacd. Данные функции изменяют car и cdr элементы cons-ячеек соответственно. Можно также использовать setf в связке с car и cdr.

Структура списка деструктивно изменяется, а не копируется. Такое поведение может оказаться неожиданным, особенно при использовании частей списком, на которые указывают более одной переменной. Описанные ранее функции nconc, nreverse, nreconc, и nbutlast также деструктивно изменяют список. Данные функции имеют «копирующие, а не разрушающие» аналоги.

[Функция] rplaca x y

(rplaca x y) изменяет car элемент в cons-ячейке x на y и возвращает (модифицированную) x. x должен быть cons-ячейкой, но y может быть любым Lisp’овым объектом. Например:

(setq g ’(a b c))
(rplaca (cdr g) ’d)  (d c)
Теперь g  (a d c)


[Функция] rplacd x y

(rplacd x y) изменяет cdr элемент в cons-ячейке x на y и возвращает (модифицированную) x. x должен быть cons-ячейкой, но y может быть любым Lisp’овым объектом. Например:

(setq x ’(a b c))
(rplacd x ’d)  (a . d)
Теперь x  (a . d)


Функции rplaca и rplacd пришли из самых ранних версий Lisp’а, как car, cdr и cons. Однако, в настоящее время, они, похоже, отходят на второй план. Все больше и больше Common Lisp программистов используют setf почти для всех изменений структур: (rplaca x y) становится (setf (car x) y) или, возможно, (setf (first x) y). Ещё более вероятно, что структура defstruct или CLOS класс используют вместо списком, если структура данных слишком сложная. В таком случае setf используется в связке с функцией доступа к слоту.