9.1 符号的组成(DONE)

即符号的各个组成部分

符号有四个组成部分,每个部分都指向对象。

Print name 符号名称

Value 符号作为变量使用时的值

Function 符号作为函数使用时的函数定义。与函数类似,这里的函数定义也包括了一个符号,按键映射,按键宏

Property list 符号的属性列表

符号名称 (print name) 通常为不可变字符串,而余下的三个组成部分均可变。

符号名称 (print name) 中以字符串的形式保存了符号的名称。符号的文本表示和其名字一一对应,因此,在 elisp 中绝不能出现两个有相同名字的符号。Lisp读取器在读取符号时,会先检索判断该符号是否存在,若该符号不存在,则创建该符号。使用 symbol-name 可以获取符号的名称。

value部分保存了符号作为变量使用时的值。将符号作为 Lisp 表达式求值时,便得到该符号对应的 value。关于如何设置,检索,局部绑定value,以及控制其作用域规则,请查阅变量章。除去一些特定符号的 value 是预先设定并无法改变的,绝大多数的符号的 value 部分可以储存任何 Lisp 对象。这些特殊符号包括: nil , t 和 以 ':' 开头的符号(这些符号称为关键字符号)。细节查阅不变变量。

function部分储存了符号作为函数使用时的函数定义。通常情况下,当我们说 “函数 foo” 时,我们实际上是在说符号foo的Function部分。在不会引起歧义的情况下,不予区分。通常情况下,符号的 Function 部分保存函数定义或宏定义,也可以储存另一个符号,按键宏,按键映射或自动加载对象。可以使用 symbol-function 获取符号的Function部分。

property list部分保存一个属性列表。可以使用 symbol-plist 获取符号的 Property list 部分。

符号的 function 和 value 部分可以为空,也就是说,这个符号可以不保存对任何对象的引用(这里要和引用void 的符号区分开,前者是什么对象都没有引用,而后者是引用了一个表示什么都没有的对象)。解引用一个什么都没有引用符号,会导致 'Symbol's value as variable is void' 之类的错误。

因为每个符号的 value 部分和 function 部分是分开的,所以在 Elisp 中,变量和函数的可以有相同的名称。比如,符号 buffer-file-name 有一个 value定义 (当前 buffer 中访问的文件的名称),同时还有一个 function定义 (一个基础的函数,用于返回文件的名称)。

buffer-file-name
    => "/gnu/elisp/symbols.texi"
(symbol-function 'buffer-file-name)
    -> #<subr buffer-file-name>

最后更新于