9.1 符号的组成

每个符号都有四个组成部分(或称 “单元(cells)”),每个部分都引用另一个对象:

Print name

符号的名称。

Value

符号作为变量时的当前值。

Function

符号的函数定义。它也可以存放一个符号、一个键盘映射表或一个键盘宏。

Property list

符号的属性列表。

打印名单元始终存放一个字符串,且不可修改。其他三个单元则可以被设置为任意 Lisp 对象。

打印名单元存放的是作为符号名称的字符串。由于符号是通过名称来文本表示的,因此不能存在两个同名符号。Lisp 读取器会保证这一点:每次读取一个符号时,它都会先查找是否已存在指定名称的符号,再决定是否新建。要获取符号的名称,可以使用函数 symbol-name(see 创建与编入符号)。不过,尽管每个符号都只有唯一的 打印名(print name),但仍然可以通过名为「简写 “shorthands”)」的不同别名来引用同一个符号(see 简写符号)。

值单元存放符号作为变量的值,也就是当符号本身被当作 Lisp 表达式求值时得到的结果。关于值如何被设置与获取,包括 局部绑定(local bindings)作用域规则(scoping rules) 等复杂细节,See 变量。大多数符号的值可以是任意 Lisp 对象,但某些特殊符号的值不可修改,包括 nilt,以及所有以 ‘:’ 开头的符号(这类符号称为 关键字(keywords))。See 永不改变的变量

函数单元存放符号的函数定义。我们常说 “foo 函数”,实际指的是存放在 foo 的函数单元中的函数;仅在必要时我们才会明确区分这两者。通常,函数单元用于存放函数(see 函数)或宏(see )。不过,它也可以用来存放符号(see 符号函数间接引用)、键盘宏(see Keyboard Macros)、键盘映射表(see Keymaps)或自动加载对象(see 自动加载)。要获取符号的函数单元内容,可使用函数 symbol-function(see 访问函数单元内容)。

属性列表单元通常应存放格式正确的属性列表。要获取符号的属性列表,可使用函数 symbol-plist。see 符号属性

值单元可以是 未绑定(void) 状态,意味着该单元没有引用任何对象。(这既不等同于存放符号 void,也不等同于存放符号 nil。)访问一个处于未绑定状态的值单元会触发错误,例如 ‘Symbol's value as variable is void’(符号作为变量的值未绑定)。

由于每个符号都拥有独立的值单元和函数单元,因此变量名与函数名不会冲突。例如,符号 buffer-file-name 既拥有一个值(当前缓冲区正在访问的文件名),同时也拥有一个函数定义(一个返回该文件名的原语函数):

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

emacs

Emacs

org-mode

Orgmode

Donations

打赏

Copyright

© 2025 Jasper Hsu

Creative Commons

Creative Commons

Attribute

Attribute

Noncommercial

Noncommercial

Share Alike

Share Alike