Макрос setf
Макрос setf — самый простой способ работы с обобщёнными переменными. Форма setf похожа на setq, за исключением того, что в качестве первого (левого) аргумента каждой пары она принимает произвольные формы места, а не только символы. Например, (setf (car a) b) устанавливает car у a в b, выполняя ту же операцию, что и (setcar a b), но без необходимости использовать две отдельные функции для установки и получения значения такого места.
- Макрос: setf [place form]…
Этот макрос вычисляет 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), поэтому в скомпилированном коде его использование не влечёт снижения производительности. - Вызов любой из следующих стандартных функций Lisp:
aref cddr symbol-function car elt symbol-plist caar get symbol-value cadr gethash cdr nth cdar nthcdr
- Вызов любой из следующих специфичных для Emacs функций:
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работают как обобщённые переменные. Например, этот код присвоит значениеzotлибо переменнойfoo, либо переменнойbar:(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 можно использовать для вставки или удаления элементов в любой позиции списка.
Аналогично, макросы incf и decf (см. Арифметические операции) можно использовать для увеличения или уменьшения числовых обобщённых переменных.
Библиотека cl-lib определяет различные расширения для обобщённых переменных, в том числе дополнительные места setf. См. раздел Обобщённые переменные в Расширениях Common Lisp.
Copyright © 1990-1996, 1998-2026 Free Software Foundation, Inc.
Licensed under the GNU GPL license.
https://www.gnu.org/software/emacs/manual/html_node/elisp/Setting-Generalized-Variables.html