拥有缓冲区局部绑定的变量,其全局值也被称为 默认值(default)——这是因为当当前缓冲区没有该变量的专属绑定(局部值)时,生效的就是这个默认值。
函数 default-value 和 setq-default 用于访问和修改变量的默认值,不受当前缓冲区是否存在该变量的缓冲区局部绑定影响。例如,你可以使用 setq-default 修改 paragraph-start 的默认设置(该设置会作用于绝大多数缓冲区);即便你正处于 C 模式或 Lisp 模式缓冲区(这类缓冲区通常为该变量设置了缓冲区局部值),此操作依然有效。
特殊形式 defvar 和 defconst 同样只会设置变量的默认值(如果它们确实对变量进行了赋值),而非任何缓冲区局部值。
该函数返回 symbol 的默认值。这是那些未为该变量设置专属值的缓冲区和框架(frame)所使用的值。若 symbol 并非缓冲区局部变量,则该函数等效于 symbol-value(see 访问变量值)。
函数 default-boundp 用于判断 symbol 的默认值是否为非未定义(nonvoid)状态。若 (default-boundp 'foo) 返回 nil,则调用 (default-value 'foo) 会触发错误。
default-boundp 与 default-value 的关系,等同于 boundp 与 symbol-value 的关系。
该特殊形式为每个 symbol(符号)赋予新的默认值,新值为对应 form(表达式)的求值结果。此操作不会对 symbol 进行求值,但会对 form 求值。整个 setq-default 形式的返回值为最后一个 form 的求值结果。
若某个 symbol 对当前缓冲区而言非缓冲区局部变量,且未被标记为自动缓冲区局部变量,则 setq-default 的效果与 setq 完全相同。若 symbol 是当前缓冲区的缓冲区局部变量,则此操作会修改「其他缓冲区将看到的值」(前提是这些缓冲区没有该变量的缓冲区局部值),但不会改变当前缓冲区所看到的该变量值。
;; In buffer ‘foo’:
(make-local-variable 'buffer-local)
⇒ buffer-local
(setq buffer-local 'value-in-foo)
⇒ value-in-foo
(setq-default buffer-local 'new-default)
⇒ new-default
buffer-local
⇒ value-in-foo
(default-value 'buffer-local)
⇒ new-default
;; In (the new) buffer ‘bar’:
buffer-local
⇒ new-default
(default-value 'buffer-local)
⇒ new-default
(setq buffer-local 'another-default)
⇒ another-default
(default-value 'buffer-local)
⇒ another-default
;; Back in buffer ‘foo’:
buffer-local
⇒ value-in-foo
(default-value 'buffer-local)
⇒ another-default
This function is like setq-default, except that symbol is
an ordinary evaluated argument.
(set-default (car '(a b c)) 23)
⇒ 23
(default-value 'a)
⇒ 23
变量可通过 let 绑定(see 局部变量)赋予某个值。此操作会让该变量的全局值被这个绑定遮蔽;此时 default-value 将返回该绑定中的值(而非全局值),且 set-default 会被阻止修改全局值(转而修改这个 let 绑定的值)。以下两个函数可在全局值被 let 绑定遮蔽时,依然能引用到全局值。
该函数返回 symbol 的 顶层(top-level) 默认值,即该变量在所有 let 绑定之外的取值。
(defvar variable 'global-value)
⇒ variable
(let ((variable 'let-binding))
(default-value 'variable))
⇒ let-binding
(let ((variable 'let-binding))
(default-toplevel-value 'variable))
⇒ global-value
该函数将 symbol 的顶层默认值设置为指定的 value。当你希望无视代码是否运行在 symbol 的 let 绑定上下文中,直接修改该符号的全局值时,这个函数会非常实用。