Was ist der Unterschied zwischen setq und defvar?

14

Was ist der Unterschied zwischen setqund defvarin Emacs Lispeln?

Unter /programming/3855862 wird die häufig verwendete lisp-Version derselben Frage angezeigt . Sind sie in Elisp gleich?

Yasushi Shoji
quelle

Antworten:

18

Sie sollten Emacs diese Frage stellen: C-h iWählen Sie das Elisp-Handbuch ( m Elisp) und durchsuchen Sie den Index nach "defvar" ( i defvar). Damit gelangen Sie zum Knoten Variablen definieren .

Emacs teilt Ihnen mit, defvardass das Anhängen einer Dokumentzeichenfolge erlaubt ist und dass, wenn die Variable bereits einen Wert hat, nichts unternommen wird .

Hier erfahren Sie auch über die Verwendung von defvarmit keinem Wert zugewiesen werden: (defvar foo). Hiermit wird angegeben , dass die Variable für einen dynamischen Gültigkeitsbereich deklariert wird .

setq hat keine dieser Eigenschaften.

defvarund setqsind ähnlich, aber nicht ganz gleich, in Emacs Lisp und Common Lisp.

Lesen Sie mehr, um mehr zu erfahren.

Drew
quelle
1
Tatsächlich deklariert defvar auch "dynamisches Scoping", wenn ein Wert angegeben ist, und das bleibt auch dann wahr, wenn die Variable bereits einen Wert hatte. OTOH "Wenn die Variable bereits einen Wert hat, dann tut sie nichts" gilt für alle gültigen Verwendungen von defvar (und der Bytecompiler sollte in den übrigen Fällen eine Warnung ausgeben, dh wenn eine Variable nach ihrer ersten Verwendung deklariert wird).
YoungFrog
es klingt also so, als wäre defvares eine globale Variable (wie im imperativen Programmierstil) und eine Konvention zur Anpassung, während setq eher einer Let-Bindung in funktionalen Programmiersprachen gleicht (mit dynamischen / lexikalischen Gültigkeitsregeln, je nachdem, welcher globale Gültigkeitsmodus aktiv ist). .......)
Nicolas
@nicolas: Bitte lies das Handbuch. setqLegt einen var-Wert fest, unabhängig davon, ob das var (Vorkommen) lokal ist. defvardeklariert eine Variable als global. (Es kann auch "buffer-local" sein:. local-variable-p) Ein var-Vorkommen, das als Funktion arg oder durch let"local" im üblichen Sinne gebunden ist. Wenn eine durch letetc. gebundene Variable global (oder pufferlokal) ist, wird für die Dauer / den Umfang eine lokale Bindung (üblicher Sinn) dafür erstellt let. Ändert innerhalb dieses Bindungsbereichs setqden lokalen Wert. Es ist besser, von einem var- Vorkommen zu sprechen , das lokal (auf Stapel) oder global (auf Heap) ist, als von einem var.
Drew
1
@nicolas: Nehmen Sie sich Zeit, um es zu lesen und erneut zu lesen. Manchmal ist das, was es sagt, präzise, ​​aber schwer zu verstehen, wie eine formale Spezifikation. Sobald Sie es erhalten haben, kann es hilfreich sein M-x report-emacs-bug, Verbesserungen vorzuschlagen, die anderen helfen könnten, es einfacher zu machen.
Drew
1
@nicolas: Beginnen Sie mit dem Verständnis einer Variablen auf dem Heap (auch bekannt als globale oder pufferlokale Variable). Wahrscheinlich verstehen Sie bereits echte lokale Variablen, d. H. Variablen auf dem Stapel . Googeln könnte auch helfen.
Drew