¿Es posible asignar múltiples valores de retorno directamente a las variables sin pasar por una variable temporal en Emacs Lisp?
Por ejemplo, supongamos que tengo una función que devuelve una lista de dos listas:
(defun test-func ()
(setq a '(a b))
(setq b '(c d))
`(,a ,b))
Si quiero asignar el primer valor de retorno a list-a
y el segundo valor de retorno a list-b
, puedo hacer esto usando una variable temporal temp
, por ejemplo:
(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)))
¿Es posible hacer esto de manera más simple? (Estoy acostumbrado a Perl y Python donde no tienes que especificar una variable temporal)
let-binding
Håkon Hægland
fuente
fuente
cl-destructuring-bind
macro. Además, ¿realmente pretendías usarsetq
dentro de adefun
?setq
crea una variable "especial" (accesible a nivel mundial), algo que normalmente pondría fuera de una función (porque tiene poco significado declarar la misma variable más de una vez, mientras que las funciones deben ejecutarse más de una vez).let
dentro de la función. No tenía planeado establecer ninguna variable global :)Respuestas:
Common Lisp tiene una instalación especial: múltiples valores , y la biblioteca de compatibilidad Emacs Lisp los emula usando listas .
Así puedes hacer
(Cargue
cl-lib
y use elcl-
prefijo para toda la funcionalidad CL en EL).NB : si mira la respuesta SO vinculada anteriormente, verá que emular MV con listas es, por decirlo suavemente, subóptimo (vea también el comentario de @ Stefan a continuación).
fuente
multiple-value-bind
lugar decl-multiple-value-bind
(solo este último parece estar documentado en el manual gnu.org/software/emacs/manual/html_node/cl/Multiple-Values.html )?cl
paquete ya no está destinado a ser utilizado. Siempre debe usar elcl-lib
paquete, que define las funciones con elcl-
prefijo ..cl-values
: es una emulación de "mejor esfuerzo" de CommonLisp,values
pero no es realmente compatible, ya que todo lo que hace es devolver una lista (es decir, es una mentira), y en mi experiencia la gente tarde o temprano termina manipulando esos como listas (es decir, rompiendo la abstracción): mejor use las listas explícitamente (y si no le gustapcase-let
, entonces use encl-destructuring-bind
lugar decl-multiple-value-bind
).Además de confiar en el
cl-lib
paquete de compatibilidad, la forma recomendada en Elisp es usarpcase
:Al lado
pcase-let
, también haypcase-dolist
,pcase-lambda
ypcase
en sí.fuente