在词法作用域下,一个符号引用到上下文中符号名字出现的地方。局部变量缺省有着词法作用域。所以如果我们在一个环境里定义一个函数,其中有一个变量叫做 ,
则无论 foo
被调用时有存在其它的 x
,主体内的 x
都会引用到那个变量:
> (let ((x 20)) (foo))
10
则函数内的 x
就不再引用到函数定义里的那个词法变量,但会引用到函数被调用时,当下所存在的任何特别变量 :
(declare (special x))
(foo))
新的变量被创建出来之后, 一个 declare
调用可以在代码的任何地方出现。 special
声明是独一无二的,因为它可以改变程序的行为。 13 章将讨论其它种类的声明。所有其它的声明,只是给编译器的建议;或许可以使程序运行的更快,但不会改变程序的行为。
在一个文件里的代码,如果你不想依赖隐式的特殊声明,可以使用 defparameter
取代,让程序看起来更简洁。
动态作用域什么时候会派上用场呢?通常用来暂时给某个全局变量赋新值。举例来说,有 11 个变量来控制对象印出的方式,包括了 ,缺省是 10
。如果你想要用 16 进制显示数字,你可以重新绑定 *print-base*
:
> (let ((*print-base* 16))
(princ 32))
32