12.3 局部变量

全局变量会持续影响整个 Lisp 程序,直到这个全局变量被修改。有时候局部变量可能更加有用。局部变量是仅仅在 Lisp 程序的某一阶段起作用的变量。当一个变量拥有一个局部的值,我们称这个变量 局部绑定 到了这个值上,而这个变量就称为局部变量。

举个例子,当一个函数被调用时,其形式参数变量便会收到一个局部的值,这个值正是之前用来调用该函数的实际参数的值。这种局部绑定仅仅在函数的内部发挥作用。再举一个例子,特殊表达式 let 显式的建立一个局部绑定,而这个局部绑定仅仅在 let 表达式中发挥作用。

当我们提到全局绑定时,我们同时再说这个值被全局性的保留了。

建立局部的绑定,会先将之前的变量值保存下来。我们称之前的变量值被隐藏了(shadowed)。在局部变量的作用域内,使用 setq 仅仅是局部绑定。当局部变量不在发挥作用后,之前被隐藏的变量便会回来。

同一个变量可以在同一时间拥有一个以上的局部绑定。(比如在嵌套的 let 表达式中)。当前的绑定则由实际生效的绑定决定。这决定了最终对变量符号求值的结果,而其中用于绑定的,实际上是 setq。

在大多数情况下,你可以认为当前的绑定时最近的一次局部绑定,或全局绑定(在没有其他局部绑定的情况下)。但是更精细的理解则取决于 “界定规则”。默认的 Emacs “界定” 方法是动态作用域规则,也就是说,当前的绑定是 Lisp 程序运行时(runtime)最近的一次绑定。具体细节请参考 动态绑定章。此外,另外一种可选的 "界定规则" 是语法绑定。

下面的两个 特殊式 let 和 let* 用于创建局部绑定。

TODO

变量还可以进行 缓冲区局部绑定。少数变量还可以进行 终端局部绑定。这些局部绑定和常规的局部绑定非常相似,只不过他们绑定的值取决于具体你处在 Emacs 中的什么位置。

最后更新于