Книга: Practical Common Lisp

Destructuring Variables

Destructuring Variables

One handy feature of LOOP I haven't mentioned yet is the ability to destructure list values assigned to loop variables. This lets you take apart the value of lists that would otherwise be assigned to a loop variable, similar to the way DESTRUCTURING-BIND works but a bit less elaborate. Basically, you can replace any loop variable in a for or with clause with a tree of symbols, and the list value that would have been assigned to the simple variable will instead be destructured into variables named by the symbols in the tree. A simple example looks like this:

CL-USER> (loop for (a b) in '((1 2) (3 4) (5 6))
do (format t "a: ~a; b: ~a~%" a b))
a: 1; b: 2
a: 3; b: 4
a: 5; b: 6
NIL

The tree can also include dotted lists, in which case the name after the dot acts like a &rest parameter, being bound to a list containing any remaining elements of the list. This is particularly handy with for/on loops since the value is always a list. For instance, this LOOP (which I used in Chapter 18 to emit a comma-delimited list):

(loop for cons on list
do (format t "~a" (car cons))
when (cdr cons) do (format t ", "))

could also be written like this:

(loop for (item . rest) on list
do (format t "~a" item)
when rest do (format t ", "))

If you want to ignore a value in the destructured list, you can use NIL in place of a variable name.

(loop for (a nil) in '((1 2) (3 4) (5 6)) collect a) ==> (1 3 5)

If the destructuring list contains more variables than there are values in the list, the extra variables are set to NIL, making all the variables essentially like &optional parameters. There isn't, however, any equivalent to &key parameters.

Оглавление книги


Генерация: 2.246. Запросов К БД/Cache: 3 / 0
поделиться
Вверх Вниз