控制流
Table of Contents
1. 逻辑运算
1.1. and
(and &rest forms)
所有 form 计算如果都不为 nil,返回最后个 form 的值,否则返回 nil。
(and 1 2 3) ; => 3 (and 1 2 nil) ; => NIL
2. do
(do varlist endlist &body body)
循环。
参数 varlist 用来定义变量,可指定初始值以及步长:
(i) ; 定义变量 i (i 0) ; 定义变量 i,并初始为 0 (i 0 (1+ i)) ; 定义变量i并初始为 0,每次循环都会调用 +1 进行自加操作
endlist 指定循环结束的条件,以及返回值:
((> i 100)) ; 结束条件为 i 大于 100 ((> i 100) i) ; 指定 do 循环的返回值 i
例:从 1 加到 100,过程中打印 i 的值,最后表达式返回相加结果:
(do ((i 0 (1+ i)) ;; 变量n作为累加器 (n 0 (+ n i)) ) ((> i 100) n) (print i))
3. dotimes
(dotimes (var count &optional result) &body body)
按次数循环。
(dotimes (i 100 i)
(print i))
result 参数可以指定 dotimes 的返回结果:
(dotimes (i 10 'bye)
(print i))
4. dolist
(dolist (var list &optional result) &body body)
迭代一个 list 对象。
- var:参数存储每次取到 list 元素的值。
- list:遍历的对象。
- result:可选参数,指定表达式。
(dolist (i '(1 2 3 4 5))
(print i))
5. return
return 能跳出循环,示例:
(dolist (i '(1 2 3 4 "5" 6 7)) (when (stringp i) (format t "found a string: ~S" i) ;; 跳出并返回 NIL (return nil)))
6. return-from
定义:
(return-from block-name [value])
可以从指定的块名中退出,比如嵌套循环中,当满足某个条件后想退出最外层的循环,示例:
(block loop1 (dotimes (i 10) (dotimes (n i) (format t "~&i:~A n:~A" i n) ;; 如果这里用 return,只会退出当前的循环,第一层循环仍然继续 (when (= i 5) (return-from loop1)))))
7. progn
(progn &rest forms)
执行多个表达式,并将表达式最后个值作为返回值。
Q:什么时候该用 progn,什么时候用 block?
A:如果需要突然退出,使用 block,其他时候则用 progn。
(progn (print 1) (print 2) 3) ;; 输出: ;; 1 ;; 2 ;; 3
8. multiple-value-prog1
(multiple-value-prog1 values-form &rest forms)
执行多个表达式,并把第一个表达式的执行结果作为返回结果。
(multiple-value-prog1 (1+ 1) (print "a") (print "b")) ;; 输出: ;; "a" ;; "b" ;; 2