标准控制结构
来源:互联网 发布:mac book pro 编辑:程序博客网 时间:2024/06/05 08:35
一:Block
Common Lisp has three basic operators for creating blocks Of code: progn, block, and tagbody.
block
A block is like a progn with a name and an emergency exit At any point within the body, you can halt evaluation and return a value immediately by using return-from with the block's name,
1:The second argument to return-from is returned as the value of the block named by the first。 return-from后第二个参数会作为以第一个参数为名字的block的值。
CL-USER> (block head (format t "Here we go.") (return-from head 'idea) (format t "We'll never see this."))Here we go.IDEA
2:There is also a return macro, which returns its argument as the value of an enclosing block named nil
CL-USER> (block nil (return 27))273: Common lisp有一些操作符比如接受很多body的话,他会把这些body隐式的包含在一个叫nil的block里面,
CL-USER> (dolist (x '(a b c d e)) (format t "~A " x) (if (eql x 'c) (return 'done)))A B C DONE
4:用defun定义的function,也会隐式的把body放入到跟他的function name一样的block里面。
CL-USER> (defun foo () (return-from foo 27))FOO
Outside of an explicit or implicit block, neither return-from nor return will work.
Tagbody
The third basic block construct is tagbody, within which you can use gotos. Atoms appearing in the body are interpreted as labels;Most iteration operators have an implicit tagbody, but Most programmers will never use tagbody explicitly.
CL-USER> (tagbody (setf x 0) top (setf x (+ x 1)) (format t "~A " x) (if (< x 10) (go top)))1 2 3 4 5 6 7 8 9 10 NIL二:Condition
If /when/unless
下面这个代码基本上也就概述了if/progn的实现功能。因为then-form和else-form都必须为单一的lisp形式,progn可以顺序执行任何数量的形式并返回最后一个形式的值。
CL-USER> (when (oddp that) (format t "Hmm, that's odd.") (+ that 1))Is equivalent to:CL-USER> (if (oddp that) (progn (format t "Hmm, that's odd.") (+ that 1)))CL-USER> (unless nil (format t "~a " 'first) (format t "~a " 'second))FIRST SECOND NILCond
当遇到多分支的条件语句时
Cond allow multiple condition. (test-1 form),只要test为真就执行form,下面的不再执行。t为不得已的处理方式
CL-USER> (defun our-member (obj 1st) (cond ((atom 1st) nil) ((eql (car 1st) obj) 1st) (t (our-member obj (cdr 1st)))))
Case: begins with an argument whose value will be compared against the keys in each clause
CL-USER> (defun month-length (mon) (case mon ((jan mar may jul aug oct dec) 31) ((apr jun sept nov) 30) (feb (if (leap-year) 29 28)) (otherwise "unknown month")))AND ,OR 和NOT
Not 接受单一形参,并对真值求反
AND 和OR都支持“短路”特性
AND 只有有一个表达式为NIL,就返回NIL,到最后无NIL,返回最后一个表达式的值。
OR 只要一个子表达式值为非NIL,就返回当前值,否则就返回NIL
三:Iterator Operator
The basic iteration operator is do, Since do contains both an implicit block and an implicit tagbody, we now know that it's possible to use return, return-f rom, and go within the body of a do
DOLIST和DOTIMES
列表循环和计数循环,这两个宏提供易用却不怎么通用的结构,对于其他无法满足的情形,仍需要在DO之上构建自定义的循环结构
The third expression within the initial list will be evaluate and return as the value of dolist /dotimes when iteration terminates, it defaults to nil.
(dolist (var list-form) body-form*) var依次从list中取出后继来执行循环体
(dotimes (var count-form) body-form*),var持有的整数从0逐增到比那个数小1
CL-USER> (dolist (x '(1 2 3))(print x))1 2 3 NILCL-USER> (dolist (x '(1 2 3))(print x)(if (evenp x)(return x)))1 2 2CL-USER> (dotimes (i 4)(print i))0 1 2 3 NIL
DO
(do (variable-definition*)
(end-test-form result-form*)
Statement*)
Variable-definition是含有三个元素的列表(var init-form step-form)
init-form 开始绑定到var, 在下一次循环开始之前step-form赋值给var。 如果step-form未给的话,var将保持不变。如果init-form未给,将绑定到NIL。
当循环开始以后,循环变量都被赋予了新值后,即新一轮的循环开始end-test-form(终止判断条件)会被求值。
当end-test-form为真时,result-form(结果形式)将被求值,
在迭代的每一步,所有的step-form将在分配任何值给变量之前被求值。意味着可以在step-form中引用其他任何循环变量(比如下面就是这一轮的用上一轮的结果)理解do循环的关键部分。为啥它能够循环执行,因为它里面还有一个判断条件(end-test-form),有一点类似java中的do while.而现在由于本身变量定义就有一定的逻辑(第三个参数给变量赋值),所以有的时候就不需要循环体之类的,并且有的时候会省略结果形式,
(= 10 n)是一个终止条件,cur 当end-test-form为真是才求值。并且因为先给参数赋予新值才会判断终止条件,所以当判断到n=10时,上一轮的next已经变为这一轮的cur.所以最后的结果cur返回了第11个斐波那契数。
CL-USER> (do ((n 0 (+ 1 n)) (cur 0 next) (next 1 (+ cur next))) ((= 10 n) cur))55上面就是斐波那契省略了结果形式,(print i)只是一个打酱油的,即statement,最后整个式子的值是NIL.CL-USER> (do ((i 0 (1+ i))) ((>= i 4)) (print i)) 0 1 2 3 NIL
以上有的时候容易造成一些混乱,关键记住6个括号是do循环必备的,
一对括号围住变量声明
一对围住终止测试和结果形式
一对围住整个表达式
(do (variable-definition*)
(end-test-form result-form*)
Statement*)
下面的例子是即使没有没有循环变量,仍需给个变量的空列表。实现的功能是,在当前时间小于一个全局变量的时候,保持循环,每分钟打印一个waiting.
CL-USER> (get-universal-time)3551729050CL-USER> (do () ((> (get-universal-time) *some-future-date*)) (format t "waiting ~%") (sleep 60))四:Context
Let allow us to establish new variables for use within the body, because entering a let is conceptually equivalent to doing a function call
CL-USER> (let ((x 7) (y 2)) (format t "Number") (+ x y))Number9The preceding l e t expression is exactly equivalent to:CL-USER> ((lambda (x y) (format t "Number") (+ x y)) 7 2)
由于我们给出了let的等价形式,那么下面这个问题就很显而易见了。
CL-USER> (let ((x 2) (y (+ x 1))) (+ x y)); undefined variable: X因为上式等价于 CL-USER> ((lambda (x y) (+ x y)) 2 (+ x 1))
Here it's obvious that the (+ x 1) passed as an argument to the function cannot refer to the parameter x within the function.
如果你想用这个X的话,就调用Let*方法。
CL-USER> (let* ((x 1)(y (+ x 1))) (+ x y))3A let* is functionally equivalent to a series of nested lets .CL-USER> (let ((x 1)) (let ((y (+ x 1))) (+ x y)))五:Multiple Values
The maximum number of return values is implementation-dependent, but it will be at least 19.
Multiple values allow a function that calculates several things to return them without having to build a structure to contain them all. For example, the built-in get-decoded time returns the current time in nine values: second,minute, hour, date, month, day, and two others.
Multiple values also make it possible to have lookup functions that can distinguish between finding nil and failing to find something.
The values function returns multiple valuesCL-USER> (multiple-value-bind (x y z) (values 1 2 3) (list x y z))(1 2 3)More variables than valuesCL-USER> (multiple-value-bind (x y z) (values 1 2) (list x y z))(1 2 NIL) Move values than variablesCL-USER> (multiple-value-bind (s m h) (get-decoded-time) (format nil "~A:~A:~A" h m s))"19:17:13"
multiple-value-call pass on multiple values as the arguments to a second function
multiple-value-list like multiple-value-call with #'list as the first argument
CL-USER> (multiple-value-call #' + (values 1 2 3)) 6CL-USER> (multiple-value-list (values 'a 'b ' c)) (A B C)
- 标准控制结构
- SVN版本控制 标准目录结构
- H.264编码标准的码率控制结构
- H.264编码标准的码率控制结构
- H.264编码标准的码率控制结构
- 控制结构
- 控制结构
- 控制结构
- 控制结构
- 控制结构
- 控制结构
- 标准访问控制列表
- 标准VBS控制Word
- 标准输入输出的控制
- maven标准目录结构
- Linux 标准目录结构
- linux 标准目录结构
- Linux 标准目录结构
- 你可能会浪费您的当前网站上的钱
- VTune安装
- vtune使用笔记
- 网易邮箱
- VTune工具使用心得
- 标准控制结构
- pojo 复合主键HQL serializable [java.lang.Object
- html5游戏开发-愤怒的小鸟-开源讲座(一)-跳入弹出的小鸟
- 如何把nokia 5320的记事本导入电脑
- Delphi TStrings取得Ini文件键值对
- QT :: Qwizard 用法
- 2012.7.20
- 【PHP】php 发送 Email
- 2012-7-20 周五 计划