Определение переменной — это конструкция, которая объявляет ваше намерение использовать символ как глобальную переменную. Она использует специальные формы defvar или defconst, которые описаны ниже.
Определение переменной служит трем целям. Во-первых, оно информирует людей, читающих код, о том, что символ предназначен использоваться определенным образом (как переменная). Во-вторых, оно информирует систему Lisp об этом, необязательно предоставляя начальное значение и строку документации. В-третьих, оно предоставляет информацию инструментам программирования, таким как etags, позволяя им найти, где была определена переменная.
Разница между defconst и defvar в основном заключается в намерении, служащем для информирования читателей о том, должна ли ее стоимость когда-либо меняться. Emacs Lisp на самом деле не запрещает вам изменять значение переменной, определенной с помощью defconst. Одна примечательная разница между двумя формами заключается в том, что defconst безусловно инициализирует переменную, тогда как defvar инициализирует ее только в том случае, если она изначально пуста.
Чтобы определить настраиваемую переменную, вы должны использовать defcustom (который вызывает defvar в качестве подпрограммы). См. Определение настраиваемых переменных.
Эта специальная форма определяет symbol как переменную и необязательно инициализирует и документирует ее. Обратите внимание, что она не вычисляет symbol; символ, который необходимо определить, должен явно присутствовать в форме defvar. defvar также помечает symbol как специальный, что означает, что его привязки всегда должны быть динамическими (см. Правила области видимости привязок переменных).
Если указан value, и symbol пуст (т.е. у него нет динамически привязанного значения; см. Когда переменная пуста), то defvar вычисляет value и инициализирует symbol, присваивая ему результат вычисления. Но если symbol не пуст, defvar не вычисляет value и оставляет значение symbol без изменений. Если value опущен, defvar ни в коем случае не изменяет значение symbol.
Обратите внимание, что указание значения, даже nil, навсегда помечает переменную как специальную. В то время как, если value опущен, defvar помечает переменную как специальную только локально (т.е. в текущей лексической области видимости или в текущем файле, если defvar находится на верхнем уровне). Это может быть полезно для подавления предупреждений о компиляции байт-кода, см. Ошибки компилятора.
Если symbol имеет локальную для буфера привязку в текущем буфере, и указан value, defvar изменяет значение по умолчанию symbol, которое не зависит от буфера, а не локальную привязку буфера. Он устанавливает значение по умолчанию, если значение по умолчанию пусто. См. Локальные переменные буфера.
Если symbol уже привязана с помощью let (например, если форма defvar встречается в форме let), то defvar устанавливает значение по умолчанию на верхнем уровне для symbol, как set-default-toplevel-value. Привязка let остается в силе до выхода из ее конструктора.
Когда вы вычисляете форму defvar на верхнем уровне с помощью C-M-x (eval-defun) или с помощью C-x C-e (eval-last-sexp) в режиме Emacs Lisp, специальная функция этих двух команд организует безусловное установление переменной, не проверяя, пуст ли ее значение.
Если предоставлен аргумент doc-string, он указывает строку документации для переменной (хранится в свойстве variable-documentation символа). См. Документация.
Вот несколько примеров. Эта форма определяет foo, но не инициализирует его:
(defvar foo)
⇒ foo
Этот пример инициализирует значение bar значением 23 и предоставляет ему строку документации:
(defvar bar 23
"Нормальный вес прута.")
⇒ bar
Форма defvar возвращает symbol, но она обычно используется на верхнем уровне в файле, где ее значение не имеет значения.
Для более подробного примера использования defvar без значения см. Пример локального defvar.
Эта специальная форма определяет symbol как значение и инициализирует его. Она информирует человека, читающего ваш код, что symbol имеет стандартное глобальное значение, установленное здесь, которое не должно изменяться пользователем или другими программами. Обратите внимание, что symbol не вычисляется; символ, который необходимо определить, должен явно присутствовать в defconst.
Форма defconst, как и defvar, помечает переменную как специальную, что означает, что она всегда должна быть динамически привязана (см. Правила области видимости привязок переменных). Кроме того, она помечает переменную как рискованную (см. Локальные переменные файла).
defconst всегда вычисляет value и устанавливает значение symbol равным результату. Если symbol имеет локальную для буфера привязку в текущем буфере, defconst устанавливает значение по умолчанию, а не локальное для буфера значение. (Но вы не должны создавать локальные для буфера привязки для символа, определенного с помощью defconst.)
Примером использования defconst является определение Emacs константы float-pi — математической константы pi, которую никто не должен менять (несмотря на попытки законодательного собрания Индианы). Однако, как показывает вторая форма, defconst является только рекомендательным.
(defconst float-pi 3.141592653589793 "Значение Пи.")
⇒ float-pi
(setq float-pi 3)
⇒ float-pi
float-pi
⇒ 3