Czy możliwe jest przypisanie wielu zwracanych wartości bezpośrednio do zmiennych bez przechodzenia przez zmienną tymczasową w Emacs Lisp?
Załóżmy na przykład, że mam funkcję, która zwraca listę dwóch list:
(defun test-func ()
(setq a '(a b))
(setq b '(c d))
`(,a ,b))
Jeśli chcę przypisać pierwszą wartość zwracaną list-a
i drugą wartość zwracaną list-b
, mogę to zrobić za pomocą zmiennej tymczasowej temp
, na przykład:
(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)))
Czy można to zrobić prościej? (Jestem przyzwyczajony do Perla i Pythona, gdzie nie musisz określać zmiennej tymczasowej)
let-binding
Håkon Hægland
źródło
źródło
cl-destructuring-bind
makro. Ponadto, czy naprawdę zamierzałeś używać wsetq
środkudefun
?setq
tworzy „specjalną” (globalnie dostępną) zmienną, coś, co zwykle umieszcza się poza funkcją (ponieważ deklarowanie tej samej zmiennej więcej niż raz ma niewiele sensu, podczas gdy funkcje mają być uruchamiane więcej niż jeden raz).let
wewnątrz funkcji. Nie planowałem ustawiać żadnych zmiennych globalnych :)Odpowiedzi:
Common Lisp ma specjalną funkcję - wiele wartości , a biblioteka kompatybilności Emacs Lisp emuluje je za pomocą list .
W ten sposób możesz zrobić
(załaduj
cl-lib
i użyjcl-
prefiksu dla wszystkich funkcji CL w EL).Uwaga : jeśli spojrzysz na odpowiedź SO podaną powyżej, zobaczysz, że emulacja MV za pomocą list jest, delikatnie mówiąc, suboptymalna (patrz również komentarz @ Stefana poniżej).
źródło
multiple-value-bind
zamiastcl-multiple-value-bind
(tylko to drugie wydaje się udokumentowane w podręczniku gnu.org/software/emacs/manual/html_node/cl/Multiple-Values.html )?cl
Pakiet nie ma być już używane. Zamiast tego zawsze powinieneś używaćcl-lib
pakietu, który definiuje funkcje zcl-
prefiksem ..cl-values
Odradzam stosowanie : jest to emulacja „Common wysiłku” CommonLisp,values
ale nie jest tak naprawdę zgodna, ponieważ wszystko, co robi, to zwrócenie listy (tj. Rodzaj kłamstwa), a według mojego doświadczenia ludzie prędzej czy później skończą manipulowanie nimi jako listami (tj. łamanie abstrakcji): lepiej używaj list jawnie (a jeśli ci się nie podobapcase-let
, użyjcl-destructuring-bind
raczej niżcl-multiple-value-bind
).Oprócz polegania na
cl-lib
pakiecie kompatybilności, zalecanym sposobem w Elisp jest użyciepcase
:Obok
pcase-let
, tam takżepcase-dolist
,pcase-lambda
ipcase
sama.źródło