É possível atribuir vários valores de retorno diretamente às variáveis sem passar por uma variável temporária no Emacs Lisp?
Por exemplo, digamos que eu tenho uma função que retorna uma lista de duas listas:
(defun test-func ()
(setq a '(a b))
(setq b '(c d))
`(,a ,b))
Se eu quiser atribuir o primeiro valor de retorno list-a
e o segundo valor de retorno list-b
, posso fazer isso usando uma variável temporária temp
, por exemplo:
(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)))
É possível fazer isso de maneira mais simples? (Estou acostumado a Perl e Python, onde você não precisa especificar uma variável temporária)
let-binding
Håkon Hægland
fonte
fonte
cl-destructuring-bind
macro. Além disso, você realmente pretendia usarsetq
dentro de umdefun
?setq
cria uma variável "especial" (acessível globalmente), algo que você normalmente colocaria fora de uma função (porque há pouco significado em declarar a mesma variável mais de uma vez, enquanto as funções devem ser executadas mais de uma vez).let
dentro da função .. Eu não planejei para definir quaisquer variáveis globais :)Respostas:
O Common Lisp possui uma instalação especial - vários valores , e a biblioteca de compatibilidade do Emacs Lisp os emula usando listas .
Assim você pode fazer
(carregue
cl-lib
e use ocl-
prefixo para toda a funcionalidade CL no EL).Nota : se você olhar para a resposta do SO vinculada acima, verá que emular MV com listas é, para dizer o mínimo, subótimo (consulte também o comentário de @ Stefan abaixo).
fonte
multiple-value-bind
vez decl-multiple-value-bind
(apenas o último parece estar documentado no manual gnu.org/software/emacs/manual/html_node/cl/Multiple-Values.html )?cl
pacote não deve ser usado mais. Você deve sempre usar ocl-lib
pacote em vez disso, que define funções com ocl-
prefixo ..cl-values
: é uma emulação de "melhor esforço" do CommonLisp,values
mas não é realmente compatível, pois tudo o que faz é retornar uma lista (isto é, é uma mentira) e, na minha experiência, as pessoas mais cedo ou mais tarde acabam manipulando-os como listas (ou seja, quebrando a abstração): use melhor as listas explicitamente (e se você não gostarpcase-let
, use emcl-destructuring-bind
vez decl-multiple-value-bind
).Além de contar com o
cl-lib
pacote de compatibilidade, a maneira recomendada no Elisp para isso é usarpcase
:Ao lado
pcase-let
, há tambémpcase-dolist
,pcase-lambda
epcase
em si.fonte