В чем разница между setq и defvar

14

Какая разница между setqи defvarв Emacs lisp?

Я вижу обычную версию этого вопроса на lisp по адресу /programming/3855862 . Они одинаковые в Элиспе?

Ясуши Сёдзи
источник

Ответы:

18

Вы должны задать Emacs этот вопрос: C-h iвыберите руководство Elisp ( m Elisp) и поищите в индексе «defvar» ( i defvar). Это приведет вас к узлу Определение переменных .

Emacs сообщает вам, что defvarпозволяет присоединить строку документа и что, если переменная уже имеет значение, она ничего не делает .

Он также сообщает вам об использовании defvarс значения не должны быть назначены: (defvar foo). Он говорит вам, что это объявляет переменную для динамической области видимости .

setq не имеет ни одного из этих свойств.

defvarи setqпохожи, но не совсем одинаковы, в Emacs Lisp и Common Lisp.

Узнайте больше, чтобы узнать больше.

Нарисовалась
источник
1
Фактически defvar также объявляет «динамическое определение объема», если задано значение, и это остается верным, даже если переменная уже имела значение. OTOH «если переменная уже имеет значение, то она ничего не делает» верна для всех допустимых применений defvar (и байт-компилятор должен выдавать предупреждение в остальных случаях, т. Е. При объявлении переменной после ее первого использования).
YoungFrog
Похоже defvar, это глобальная переменная (как в императивном стиле программирования) и соглашение для настройки, в то время как setq больше похож на привязку let в функциональных языках программирования (с правилом динамической / лексической области видимости, зависящим от того, какой режим глобальной области видимости активен). .......)
Николас
@nicolas: Пожалуйста, прочтите руководство. setqустанавливает значение переменной, независимо от того, является ли переменная (вхождение) локальной. defvarобъявляет переменную как глобальную. (Это может быть также «локальный буфер»:. local-variable-p) Вхождение var, связанное как функция arg, или let«local» в обычном смысле. Если переменная, связанная с letи т. Д., Является глобальной (или локальной для буфера), то для нее создается локальная привязка (в обычном смысле) на весь период действия let. В этой области привязки setqизменяет локальное значение. Лучше говорить о том, что вхождение var является локальным (в стеке) или глобальным (в куче), чем var.
Дрю
1
@nicolas: не торопитесь, читая это и перечитывая это. Иногда то, что оно говорит, является точным, но трудно понять, как формальная спецификация. Как только вы его получите, вам может быть полезно M-x report-emacs-bugпредложить улучшения, которые могут помочь другим сделать это проще.
Дрю
1
@nicolas: Начните с понимания переменной в куче (она же глобальная или локальная переменная буфера). Вы, вероятно, уже понимаете истинные локальные переменные, то есть переменные в стеке . Гугл также может помочь.
Дрю