宏:标准控制构造

WHEN和UNLESS

基本的条件执行形式是由IF特殊操作符提供的,其基本形式是:如果x成立,那么执行y,否则执行z

(if condition then-form [else-form])
(if (> 2 3) "Yup" "Nope")
(if (> 2 3) "Yup")
(if (> 3 2) "Yup" "Nope")

如果要执行多个语句,可以使用progn

(if (< 2 3)
    (progn
        (format t "yes")
        (format t "no")))

; yesno
; NIL

系统也提供了一个更简单的宏来执行这个操作,可以使用when宏来完成

(when (> 4 2)
    (format t "yes")
    (format t "no"))

; yesno
; NIL

COND

当遇到多重分支的条件语句时,原始的IF表达式会变得丑陋不堪,这个时候,我们可以选择使用COND

(cond
    (test-1 form*)
    (test-2 form*)
    ...
    (test-3 form*))

会在主体中出现的顺序被依次求值,直到它们中一个求值为真。这时,该分支中其余形式将被求值,且分支中最后一个形式的值将作为整个COND的返回值

(cond 
    (a (do-x))
    (b (do-y))
    (c (do-z))
    )
(defparameter *value* 4)
(cond 
    ((> *value* 2) (format t "yes2"))
    ((> *value* 3) (format t "yes3"))
    ((> *value* 4) (format t "yes4"))
    ((> *value* 5) (format t "yes5"))
    )

; yes2
; NIL

AND、OR和NOT

一些例子

CL-USER> (not nil)
T
CL-USER> (not (= 1 1))
NIL
CL-USER> (and (= 1 2) (= 3 3))
NIL
CL-USER> (or (= 1 2) (= 3 4))
NIL
CL-USER> 

DOLIST和DOTIMES

下面是DOLIST的基本形式

(dolist (var list-form)
    body-form*)

当循环开始时,list-form被求值一次以产生一个列表,然后循环体在列表的每一项山求值一次,同时用变量var保存当前项的值

(dolist (x '(1 2 3)) (print x) )

; 1 
; 2 
; 3 
; NIL

在这种方式下,DOLIST这种形式本身求值为NIL

(dolist ( x '(1 2 3) )
    (print x)
    (if (= x 2)
        (return)
     ))
; 1 
; 2 
; NIL

DOTIMES是用于循环计数的高级循环构造,其基本末班和DOLIST非常相似

(dotimes (var count-form)
    body-form*)

其中count-form必须要能求值为一个整数。通过每次循环,var所持有的整数依次为从0到比那个数小1的每一个后继整数

(dotimes (i 4) (print i) )

; 0 
; 1 
; 2 
; 3 
; NIL

DO

DO允许绑定任意数量的变量,并且变量值在每次循环中改变方式也是完全可控的也可以定义测试条件来决定何时终止循环,并可以提供一个形式,在循环结束时进行求值来为DO表达式整体生成一个返回值

(do (variable-definition*)
    (end-test-form result-form*)
    statement*)
  • 每一个variable-definition引入了一个将存在于循环体作用域之内的变量。单一变量定义的完整形式是一个含有三个元素的列表
(var init-form step-form)
  • init-form在开始时被求值并将结果值绑定到变量var上
  • step-form将被求值并把新值分配给var
  • 每次迭代开始时以及所有循环变量都被指定新值后,end-test-form会被求值
  • end-test-form求值为真时,result-form将被求值,且最后一个结果形式的值将被作为DO表达式的值返回
  • end-test-form值如果为NIL,迭代过程就会继续,依次求值所有的statement
;该实例中结果形式被省略了
(do ( (i 0 (+ 1 i) ) )
    ( (>= i 4) )
    (print i)
 )

; 0 
; 1 
; 2 
; 3 
; NIL

强大的Loop

如果要使用宏来做收集、计数、求和、最小化和最大化,那么LOOP宏可以提供一种更容易表达的方式

;简化版,就是一个不绑定任何变量的无限循环
(loop
 body-form*
 )

主体形式在每次通过循环时都将被求值,整个循环将不停的迭代,直到使用RETURN来进行中止

© 版权声明
THE END
喜欢就支持以下吧
点赞0
分享
评论 抢沙发
四曲的头像-四曲博客

昵称

取消
昵称表情代码图片