setfМакрос setf — самый базовый способ работы с обобщенными
переменными. Форма setf похожа на setq, за исключением того, что она
принимает произвольные формы места в первом (левом) аргументе каждой пары, а не только символы. Например, (setf (car a) b)
устанавливает car a в b, выполняя ту же операцию, что и
(setcar a b), но без необходимости использовать две отдельные
функции для установки и доступа к такому месту.
Этот макрос вычисляет form и сохраняет его значение в place,
которое должно быть допустимой формой обобщенной переменной. Если существует несколько
пар place и form, присваивания выполняются последовательно,
как и с setq. setf возвращает значение последней
form.
Следующие формы Lisp — это формы в Emacs, которые будут работать как
обобщенные переменные, и поэтому могут появляться в аргументе place
setf:
(setf x y) эквивалентен
(setq x y), и сам setq строго говоря
избыточен, учитывая существование setf. Тем не менее, большинство
программистов по-прежнему предпочитают setq для установки простых
переменных, по стилистическим и историческим причинам. Макрос (setf x y)
фактически расширяется до (setq x y), поэтому нет никаких
проблем с производительностью при использовании его в скомпилированном коде.
aref cddr symbol-function car elt symbol-plist caar get symbol-value cadr gethash cdr nth cdar nthcdr
alist-get overlay-start default-value overlay-get face-background process-buffer face-font process-filter face-foreground process-get face-stipple process-sentinel face-underline-p terminal-parameter file-modes window-buffer frame-parameter window-dedicated-p frame-parameters window-display-table get-register window-hscroll getenv window-parameter keymap-parent window-point match-data window-start overlay-end
(substring subplace n [m]),
где subplace сама является допустимой обобщенной переменной, текущее
значение которой — строка, и где хранимое значение также является строкой. Новая строка
вставляется в указанную часть целевой строки. Например:
(setq a (list "hello" "world"))
⇒ ("hello" "world")
(cadr a)
⇒ "world"
(substring (cadr a) 2 4)
⇒ "rl"
(setf (substring (cadr a) 2 4) "o")
⇒ "o"
(cadr a)
⇒ "wood"
a
⇒ ("hello" "wood")
if и cond будут работать как
обобщенные переменные. Например, это установит либо переменную foo, либо
bar в zot:
(setf (if (zerop (random 2))
foo
bar)
'zot)
setf сигнализирует об ошибке, если вы передаете форму place, которую
он не знает, как обработать.
Обратите внимание, что для nthcdr аргумент списка функции сам должен быть
допустимой формой place. Например, (setf (nthcdr
0 foo) 7) установит саму foo в 7.
Макросы push (см. Изменение переменных списка) и pop
(см. Доступ к элементам списков) могут манипулировать обобщенными
переменными, а не только списками. (pop place) удаляет и возвращает
первый элемент списка, хранящегося в place. Это аналогично
(prog1 (car place) (setf place (cdr place))),
за исключением того, что он гарантирует вычисление всех подформ только один раз.
(push x place) вставляет x в начало
списка, хранящегося в place. Это аналогично (setf
place (cons x place)), за исключением
вычисления подформ. Обратите внимание, что push и pop для
места nthcdr могут использоваться для вставки или удаления в любой позиции в списке.
Библиотека cl-lib определяет различные расширения для обобщенных
переменных, включая дополнительные места setf.
См. Обобщенные переменные в Расширения Common Lisp.