Quelle est la différence entre setq et defvar

14

Quelle est la différence entre setqet defvardans Emacs lisp?

Je vois une version lisp courante de la même question sur /programming/3855862 . Sont-ils les mêmes dans Elisp?

Yasushi Shoji
la source

Réponses:

18

Vous devriez poser cette question à Emacs :, C-h ichoisissez le manuel Elisp ( m Elisp), et recherchez l'index "defvar" ( i defvar). Cela vous amène au nœud Définition des variables .

Emacs vous indique que defvarpermet de joindre une chaîne de doc , et que si la variable a déjà une valeur, elle ne fait rien .

Il vous indique également sur l'utilisation de defvarsans valeur à attribuer: (defvar foo). Il vous indique que cela déclare que la variable a une portée dynamique .

setq n'a aucune de ces propriétés.

defvaret setqsont similaires, mais pas tout à fait les mêmes, dans Emacs Lisp et Common Lisp.

En savoir plus, pour en savoir plus.

A dessiné
la source
1
En fait, defvar déclare également "portée dynamique" si une valeur est donnée, et cela reste vrai même si la variable avait déjà une valeur. OTOH "si la variable a déjà une valeur alors elle ne fait rien" est vraie pour toutes les utilisations valides de defvar (et le bytecompiler devrait émettre un avertissement dans les cas restants, c'est-à-dire s'il déclare une variable après sa première utilisation).
YoungFrog
il semble donc que defvarc'est une variable globale (comme dans le style de programmation impératif) et une convention pour la personnalisation, tandis que setq est plus comme une liaison let dans les langages de programmation fonctionnels (avec une règle de portée dynamique / lexicale selon le mode de portée global qui est actif. .......)
nicolas
@nicolas: Veuillez lire le manuel. setqdéfinit une valeur var, que la var (occurrence) soit locale ou non. defvardéclare un var comme global. (Il peut également être « tampon local »: local-variable-p.) Un événement de var lié comme un argument de la fonction ou letest « local » dans le sens habituel. Si un var lié par letetc. est global (ou buffer-local) alors une liaison locale (sens habituel) est créée pour lui, pour la durée / portée de cela let. Dans cette portée de liaison, setqmodifie la valeur locale. Il vaut mieux parler d'une occurrence de var étant locale (sur la pile) ou globale (sur le tas) qu'une var étant ainsi.
Drew
1
@nicolas: Prenez votre temps pour le lire et le relire. Parfois, ce qu'il dit est précis mais difficile à saisir, comme une spécification formelle. Une fois que vous l'avez obtenu, il pourrait être utile pour vous M-x report-emacs-bugde suggérer des améliorations qui pourraient aider les autres à le faire plus facilement.
Drew
1
@nicolas: Commencez par comprendre une variable sur le tas (alias une variable globale ou tampon-locale). Vous comprenez probablement déjà les vraies variables locales, c'est-à-dire les variables de la pile . La recherche sur Google pourrait également aider.
Drew