destructuring-bind — 리스트 구조를 한 번에 풀어 담기
destructuring-bind — 리스트 구조를 한 번에 풀어 담기
함수 인자를 받을 때는 lambda-list가 알아서 각 인자를 변수에 담아줘요. 그런데 지금 필요한 값이 함수 인자가 아니라, 리스트 안 깊은 곳에 들어 있는 값이라면 어떨까요? 매번 car와 cdr을 조합해 직접 풀어야 한다면 여간 번거롭지 않아요. destructuring-bind는 바로 그 자리에서 리스트 구조를 패턴에 맞춰 한꺼번에 변수로 풀어주는 매크로예요.
본문
destructuring-bind는 lambda-list에 지정된 변수들을, expression을 평가해서 얻은 트리 구조의 값들에 대응시켜 묶은 다음 forms를 평가해요.
destructuring-bind lambda-list expression declaration* form*
=> result*
지정할 수 있는 lambda-list는 일반 함수의 인자 목록과 달리, 구조 분해(destructuring) 람다 리스트예요. 즉 리스트의 각 자리마다 (key &optional default) 같은 세부 패턴을 다시 넣을 수 있어요.
(defun iota (n) (loop for i from 1 to n collect i)) ; helper
(destructuring-bind ((a &optional (b 'bee)) one two three)
`((alpha) ,@(iota 3))
(list a b three two one))
=> (ALPHA BEE 3 2 1)
백쿼트와 ,@(iota 3) 덕분에 전체 인자로 ((alpha) 1 2 3)이 넘어와요. 패턴의 첫 자리 (a &optional (b 'bee))가 (alpha)와 맞물리면서 a에는 alpha가, 지정되지 않은 b에는 기본값 bee가 들어가고, 나머지 one two three에는 1 2 3이 차례대로 담기죠.
예외 상황
평가 결과가 분해 패턴과 맞지 않으면 error 타입의 오류가 신호되어야 해요.
함께 보기
macrolet, defmacro