--------------------2015-3-11--------------------
变量:
Common Lisp 支持两种类型的变量:词法(lexical)变量和动态(dynamic)变量。
这两种变量分别对应于其他语言中的局部变量和全局变量(大致相似)。
*动态变量有时也称为特殊变量(special variable)
变量的基础知识:
Common Lisp 中的变量是一些可以保存值的具名位置。
在Common Lisp 中一个变量可以保存任何类型的值,并且这些值带有可用于运行期类型检查的类型信息。
Common Lisp 是动态类型的——类型错误会被动态地检测到。
引入新变量的方式:
1.函数形参:
(defun foo (x y z) (+ x y z))
每当函数被调用时,Lisp 就会创建新的绑定来保存由函数调用者所传递的实参。
2.LET 变量:
(let (variable*) body-form*)
其中每一个 variable 都是一个变量初始化形式。每一个初始化形式要么是一个含有变量名和初始值形式的列表,要么就是一个简单的变量名——作为将变量初始化到NIL的简略写法。
如:(let ((x 10) (y 20) z) ...)
在 LET 形式体重,变量名将引用新创建的绑定。在 LET 形式体执行结束后,这些变量名将重新引用在执行 LET 之前它们所引用的内容,如果有的话。
函数形参和 LET 变量的作用域(变量名可用来引用该绑定的程序区域)被限定在引入该变量的形式之内,该形式即函数定义或 LET,被称为绑定形式。
如果嵌套了引入同名变量的绑定形式,那么最内层的变量绑定将 覆盖 外层的绑定。
(defun foo (x)
(format t "Parameter: ~a~%" x)
(let ((x 2))
(format t "Outer LET: ~a~%" x)
(let ((x 3))
(format t "Inner LET: ~a~%" x))
(format t "Outer LET: ~a~%" x))
(format t "Parameter: ~a~%" x))
调用结果:
CL-USER> (foo 1)
Parameter: 1
Outer LET: 2
Inner LET: 3
Outer LET: 2
Parameter: 1
NIL
另一个绑定形式是 LET 的变体: LET*
与 LET 的区别:在一个 LET 中,被绑定的变量名只能用在 LET 的形式体之内—— LET 形式中变量列表之后的那部分;但在一个 LET* 中,每个变量的初始值形式,都可以引用到那些在变量列表中早先引入的变量。
如:
(let* ((x 10)
(y (+ x 10)))
(list x y))
但 不能 这样写:
(let ((x 10)
(y (+ x 10)))
(list x y))
不过也可以通过嵌套的 LET 来达到相同的效果:
(let ((x 10))
(let ((y (+ x 10)))
(list x y)))
变量:
Common Lisp 支持两种类型的变量:词法(lexical)变量和动态(dynamic)变量。
这两种变量分别对应于其他语言中的局部变量和全局变量(大致相似)。
*动态变量有时也称为特殊变量(special variable)
变量的基础知识:
Common Lisp 中的变量是一些可以保存值的具名位置。
在Common Lisp 中一个变量可以保存任何类型的值,并且这些值带有可用于运行期类型检查的类型信息。
Common Lisp 是动态类型的——类型错误会被动态地检测到。
引入新变量的方式:
1.函数形参:
(defun foo (x y z) (+ x y z))
每当函数被调用时,Lisp 就会创建新的绑定来保存由函数调用者所传递的实参。
2.LET 变量:
(let (variable*) body-form*)
其中每一个 variable 都是一个变量初始化形式。每一个初始化形式要么是一个含有变量名和初始值形式的列表,要么就是一个简单的变量名——作为将变量初始化到NIL的简略写法。
如:(let ((x 10) (y 20) z) ...)
在 LET 形式体重,变量名将引用新创建的绑定。在 LET 形式体执行结束后,这些变量名将重新引用在执行 LET 之前它们所引用的内容,如果有的话。
函数形参和 LET 变量的作用域(变量名可用来引用该绑定的程序区域)被限定在引入该变量的形式之内,该形式即函数定义或 LET,被称为绑定形式。
如果嵌套了引入同名变量的绑定形式,那么最内层的变量绑定将 覆盖 外层的绑定。
(defun foo (x)
(format t "Parameter: ~a~%" x)
(let ((x 2))
(format t "Outer LET: ~a~%" x)
(let ((x 3))
(format t "Inner LET: ~a~%" x))
(format t "Outer LET: ~a~%" x))
(format t "Parameter: ~a~%" x))
调用结果:
CL-USER> (foo 1)
Parameter: 1
Outer LET: 2
Inner LET: 3
Outer LET: 2
Parameter: 1
NIL
另一个绑定形式是 LET 的变体: LET*
与 LET 的区别:在一个 LET 中,被绑定的变量名只能用在 LET 的形式体之内—— LET 形式中变量列表之后的那部分;但在一个 LET* 中,每个变量的初始值形式,都可以引用到那些在变量列表中早先引入的变量。
如:
(let* ((x 10)
(y (+ x 10)))
(list x y))
但 不能 这样写:
(let ((x 10)
(y (+ x 10)))
(list x y))
不过也可以通过嵌套的 LET 来达到相同的效果:
(let ((x 10))
(let ((y (+ x 10)))
(list x y)))