Можно ли назначить несколько возвращаемых значений непосредственно переменным, не проходя временную переменную в Emacs Lisp?
Например, допустим, у меня есть функция, которая возвращает список из двух списков:
(defun test-func ()
(setq a '(a b))
(setq b '(c d))
`(,a ,b))
Если я хочу назначить первое возвращаемое значение list-a
и второе возвращаемое значение list-b
, я могу сделать это с помощью временной переменной temp
, например:
(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)))
Можно ли сделать это проще? (Я привык к Perl и Python, где вам не нужно указывать временную переменную)
let-binding
Хокон Хагланд
источник
источник
cl-destructuring-bind
макрос. Кроме того, вы действительно намеревались использоватьsetq
внутриdefun
?setq
создает «специальную» (глобально доступную) переменную, которую вы обычно помещаете вне функции (поскольку нет смысла объявлять одну и ту же переменную более одного раза, в то время как функции предназначены для запуска более одного раза).let
внутри функции .. Я не планировал устанавливать какие-либо глобальные переменные :)Ответы:
Common Lisp имеет специальное средство - множественные значения , и библиотека совместимости Emacs Lisp эмулирует их, используя списки .
Таким образом, вы можете сделать
(загрузить
cl-lib
и использоватьcl-
префикс для всех функций CL в EL).NB : если вы посмотрите на ответ SO, связанный выше, вы увидите, что эмуляция MV со списками, мягко говоря, неоптимальна (см. Также комментарий @ Stefan ниже).
источник
multiple-value-bind
вместоcl-multiple-value-bind
(кажется, что только последнее описано в руководстве gnu.org/software/emacs/manual/html_node/cl/Multiple-Values.html )?cl
Пакет не предназначен для использования больше. Вы должны всегда использоватьcl-lib
пакет вместо этого, который определяет функции сcl-
префиксом ..cl-values
: это эмуляция «наилучшего усилия» CommonLisp,values
но она не совсем совместима, поскольку все, что она делает, это возвращает список (то есть это своего рода ложь), и, по моему опыту, люди рано или поздно заканчивают тем, что манипулирование ими как списками (то есть нарушение абстракции): лучше использовать списки явно (и если вам не нравитсяpcase-let
, то используйтеcl-destructuring-bind
вместоcl-multiple-value-bind
).Кроме того
cl-lib
, в Elisp рекомендуется использовать пакет совместимостиpcase
:Кроме
pcase-let
, есть такжеpcase-dolist
,pcase-lambda
иpcase
сам по себе.источник