Je m'apprends un peu plus et j'ai rencontré le problème suivant:
Si je veux réinitialiser une variable de liste, elle ne sera pas mise à jour après la première évaluation. Voici un exemple de code:
(defun initilize ()
(setq example '(3)))
(defun modify ()
(initilize)
(message "%S" example)
(setcar example 2))
; M-x eval-buffer RET
(modify) ; message --> (3)
(modify) ; message --> (2)
(modify) ; message --> (2)
Je m'intéresse à deux choses. La première consiste à en savoir plus sur ce qui se passe "sous le capot", alors pourquoi cela fonctionne-t-il la première fois et échoue lors des appels suivants?
La deuxième question, plus pratique, est de savoir comment réinitialiser correctement la liste ou existe-t-il une autre façon courante de faire quelque chose comme ça?
Une solution de contournement que je me suis trouvée consiste à utiliser une liste citée et à évaluer le contenu comme ceci:
(setq example `(,3))
example
n'a jamais été déclaré en tant que variable, il setq
doit donc agir comme s'il déclarait une nouvelle variable, mais plus tard, lorsque vous appelez à initialize
nouveau, une nouvelle variable est en cours de création, tout en se modify
souvenant de l'ancienne ... dans tous les cas, ce n'est pas un comportement attendu, cependant, l'utilisation de setq
avec quelque chose qui n'a pas été introduit plus tôt comme variable pourrait tout aussi bien être indéfinie.
'(3)
est traité comme une valeur littérale, donc une fois que vous (setcar '(3) 2)
, quand vous le ferez (defvar foo '(3))
ou (let ((foo '(3)))
ainsi de suite, vous obtiendrez probablement une valeur foo
égale à '(2)
. Je dis "probable" parce que ce comportement n'est pas garanti, c'est une sorte d'optimisation que l'interprète fait chaque fois qu'il le souhaite, quelque chose appelé élimination de la sous-expression des constantes (un cas particulier de). Donc, ce qu'abo-abo a écrit n'est pas exactement la raison. Cela ressemble plus à la modification d'un littéral de chaîne en C (ce qui génère généralement un avertissement).
'(some list)
à êtreeq
à'(some list)
- jamais .Il est généralement aucune garantie dans ce code Lisp qui cite visiblement un rendement de liste nouvelle structure de la liste à chaque fois. Dans certaines implémentations Lisp, cela peut ou peut parfois arriver. Dans d'autres, ce n'est jamais le cas. Votre code ne devrait de toute façon pas dépendre d'un tel comportement de l'implémentation. Si vous voulez une nouvelle structure de liste, utilisezlist
oucons
ou équivalent.