do 循环

Common Lisp 中的大多数循环和条件结构实际上是隐藏更多基本结构的 。例如,dotimesdolist 建立在 do 宏上。do 的形式如下:

(do (varlist)
    (endlist)
   &body)
  • varlist 由循环中定义的变量,它们的初始值以及它们在每次迭代后如何变化组成。在循环结束时评估更改部分。
  • endlist 包含结束条件和循环结束时返回的值。在循环开始时评估结束条件。

这是从 0 开始并向上(不包括)10 的那个。

;;same as (dotimes (i 10)) 
(do (( i (+ 1 i))
    ((< i 10) i)
   (print i))

这是一个在列表中移动的:

;;same as (dolist (item given-list)
(do ((item (car given-list))
     (temp list (cdr temp))
   (print item))

varlist 部分类似于 let 声明中的部分。你可以绑定多个变量,它们只存在于循环内。声明的每个变量都在其自己的括号中。这是一个计算列表中有多少 1 和 2 的人。

(let ((vars (list 1 2 3 2 2 1)))
  (do ((ones 0)
       (twos 0)
       (temp vars (cdr temp)))
      ((not temp) (list ones twos))
    (when (= (car temp) 1)
      (setf ones (+ 1 ones)))
    (when (= (car temp) 2)
      (setf twos (+ 1 twos)))))
-> (2 3)

如果还没有实现 while 循环宏:

(do ()
    (t)
  (when task-done
    (break)))

对于最常见的应用程序,更具体的 dotimesdoloop 宏更简洁。