Est-il possible d'affecter plusieurs valeurs de retour directement aux variables sans passer par une variable temporaire dans Emacs Lisp?
Par exemple, supposons que j'ai une fonction qui renvoie une liste de deux listes:
(defun test-func ()
(setq a '(a b))
(setq b '(c d))
`(,a ,b))
Si je veux affecter la première valeur de retour à list-a
et la deuxième valeur de retour à list-b
, je peux le faire en utilisant une variable temporaire temp
, par exemple:
(let* ((temp (test-func)) (list-a (car temp)) (list-b (cadr temp)))
(message-box (prin1-to-string list-a))
(message-box (prin1-to-string list-b)))
Est-il possible de faire cela plus simplement? (Je suis habitué à Perl et Python où vous n'avez pas besoin de spécifier une variable temporaire)
let-binding
Håkon Hægland
la source
la source
cl-destructuring-bind
macro. Aussi, aviez-vous vraiment l'intention d'utiliser à l'setq
intérieur d'undefun
?setq
crée une variable "spéciale" (accessible globalement), quelque chose que vous mettriez généralement en dehors d'une fonction (car il n'y a pas de sens à déclarer la même variable plus d'une fois, alors que les fonctions sont destinées à être exécutées plusieurs fois).let
intérieur de la fonction .. Je n'avais pas prévu de définir de variables globales :)Réponses:
Common Lisp a une fonction spéciale - plusieurs valeurs , et la bibliothèque de compatibilité Emacs Lisp les émule à l'aide de listes .
Ainsi vous pouvez faire
(chargez
cl-lib
et utilisez lecl-
préfixe pour toutes les fonctionnalités CL dans EL).NB : si vous regardez la réponse SO liée ci-dessus, vous verrez que l'émulation de MV avec des listes est, pour le dire légèrement, sous-optimale (voir aussi le commentaire de @ Stefan ci-dessous).
la source
multiple-value-bind
au lieu decl-multiple-value-bind
(seul ce dernier semble être documenté dans le manuel gnu.org/software/emacs/manual/html_node/cl/Multiple-Values.html )?cl
package n'est plus destiné à être utilisé. Vous devriez toujours utiliser lecl-lib
package à la place, qui définit les fonctions avec lecl-
préfixe ..cl-values
: c'est une émulation de "meilleur effort" de CommonLispvalues
mais ce n'est pas vraiment compatible car il ne fait que renvoyer une liste (c'est à dire que c'est un mensonge), et d'après mon expérience, les gens se retrouvent tôt ou tard les manipuler comme des listes (c'est-à-dire rompre l'abstraction): mieux utiliser les listes explicitement (et si vous n'aimez paspcase-let
, alors utilisezcl-destructuring-bind
plutôt quecl-multiple-value-bind
).En plus de compter sur le
cl-lib
package de compatibilité, la manière recommandée dans Elisp pour cela est d'utiliserpcase
:A côté
pcase-let
, il y a aussipcase-dolist
,pcase-lambda
etpcase
lui - même.la source