# 9.1 符号的组成(DONE)

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

**Print name**\
&#x20; **符号名称**

**Value**\
&#x20; **符号作为变量使用时的值**

**Function**\
&#x20; **符号作为函数使用时的函数定义。与函数类似，这里的函数定义也包括了一个符号，按键映射，按键宏**

**Property list**\
&#x20; **符号的属性列表**

符号名称 (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>
```
