dolist 宏例如,假设您想反转一个列表,使得“first” “second” “third” 变成 “third” “second” “first”。
实际上,您可以使用 reverse 函数,如下所示:
(setq animals '(gazelle giraffe lion tiger)) (reverse animals)
以下是使用 while 循环反转列表的方法:
(setq animals '(gazelle giraffe lion tiger))
(defun reverse-list-with-while (list)
"使用while循环反转LIST的顺序。"
(let (value) ; 确保列表从空开始
(while list
(setq value (cons (car list) value))
(setq list (cdr list)))
value))
(reverse-list-with-while animals)
以下是使用 dolist 宏的方法:
(setq animals '(gazelle giraffe lion tiger))
(defun reverse-list-with-dolist (list)
"使用dolist宏反转LIST的顺序。"
(let (value) ; 确保列表从空开始
(dolist (element list value)
(setq value (cons element value)))))
(reverse-list-with-dolist animals)
在Info中,您可以将光标放在每个表达式的右括号后,然后键入 C-x C-e; 在每种情况下,您应该在回显区域看到
(tiger lion giraffe gazelle)
对于此示例,现有的 reverse 函数显然是最好的选择。
while 循环就像我们的第一个示例一样(see 一个while循环和一个列表)。while 首先检查列表是否有元素;如果有,它通过将列表的第一个元素添加到现有列表(在循环的第一次迭代中是 nil)来构造一个新列表。由于第二个元素在第一个元素的前面添加,第三个元素在第二个元素的前面添加,因此列表被反转。
在使用 while 循环的表达式中,
(setq list (cdr list))
表达式缩短了列表,因此 while 循环最终停止。此外,它通过在每次循环重复时创建一个新的更短的列表,为 cons 表达式提供了一个新的第一个元素。
dolist 表达式的工作方式与 while 表达式非常相似,不同之处在于,dolist 宏执行了在编写 while 表达式时必须执行的一些工作。
像 while 循环一样,dolist 循环。不同之处在于,它每次循环都会自动缩短列表—它会对列表进行 CDR 操作—并且会自动将每个较短版本的列表的 CAR 绑定到其第一个参数。
在此示例中,较短版本的列表的 CAR 由符号 ‘element’ 引用,列表本身称为 ‘list’,返回的值称为 ‘value’。dolist 表达式的其余部分是主体。
dolist 表达式将较短版本的列表的 CAR 绑定到 element,然后评估表达式的主体;然后重复循环。结果在 value 中返回。