목록 자체를 바인딩하지 않고 목록에서 직접 여러 값을 바인딩


12

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에 익숙하다)


2
cl-destructuring-bind매크로를 사용해보십시오 . 또한 실제로 setq내부 에서 사용하려고 defun했습니까? setq함수가 두 번 이상 실행되도록 의도 된 반면 같은 변수를 두 번 이상 선언하는 데 의미가 거의 없기 때문에 일반적으로 함수 외부에 놓이는 "특수"(전역 적으로 액세스 가능한) 변수를 만듭니다.
wvxvw

@wvxvw 감사합니다! 예 let, 함수 내부에서 사용하는 것을 잊었습니다 . 전역 변수를 설정하지 않았습니다. :)
Håkon Hægland

답변:


8

Common Lisp에는 특수한 시설 다중 값 이 있으며 Emacs Lisp 호환성 라이브러리 는 목록을 사용하여이를 에뮬레이션합니다 .

따라서 당신은 할 수 있습니다

(defun test-fun ()
  (let ((a 1) (b 2))
    (cl-values a b)))

(cl-multiple-value-bind (a b) (test-fun)
  ...)

( EL의 모든 CL 기능에 대한 접두사를 로드 cl-lib하고 사용하십시오 cl-).

주의 : 위에 링크 된 SO 답변을 보면 MV를 목록으로 에뮬레이트하는 것이 약간 차분하지 않음을 알 수 있습니다 (아래 @Stefan의 의견 참조).


multiple-value-bind대신 에 사용하는 이점이 있습니까? cl-multiple-value-bind(후자 만 gnu.org/software/emacs/manual/html_node/cl/Multiple-Values.html 설명서에 문서화되어있는 것 같습니다 )?
Håkon Hægland

3
@ HåkonHægland 그것들은 같은 기능이지만 후자를 사용해야합니다 . 이 cl패키지는 더 이상 사용되지 않습니다. 접두사 cl-lib가있는 함수를 정의 하는 패키지를 항상 대신 사용해야합니다 cl-.
Malabarba

1
나는 사용하지 않는 것이 좋습니다 cl-values: CommonLisp의 "최선의 노력"에뮬레이션 values이지만 목록을 반환하기 때문에 실제로 호환되지는 않습니다 (즉, 일종의 거짓말). 제 경험상 사람들은 조만간 끝납니다. 그것들을리스트로 조작하기 (즉, 추상화를 깨뜨리는 것) :리스트를 명시 적으로 사용하는 것이 더 좋습니다 (그리고 마음에 들지 않으면 대신 오히려 pcase-let사용하십시오 ). cl-destructuring-bindcl-multiple-value-bind
Stefan

4

cl-lib호환성 패키지 에 의존하는 것 외에도 Elisp에서 권장되는 방법은 다음을 사용하는 것입니다 pcase.

(defun test-fun
  (let ((a '(a b))
        (b '(c d)))
    `(,a ,b)))

(defun other-test-fun ()
  (pcase-let ((`(,a ,b) (test-fun)))
    (message "a = %s; b = %s" a b)))

옆에 pcase-let, 또한 거기이다 pcase-dolist, pcase-lambda그리고 pcase그 자체.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.