> For the complete documentation index, see [llms.txt](https://emacs-lisp.ivory.cafe/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://emacs-lisp.ivory.cafe/bian-liang/ding-yi-bian-liang-de-xiao-tie-shi.md).

# 12.6 定义变量的建议

当你定义的变量的 value 是函数，或者一个函数列表时，你最好分别用以 '-function' 或 '-functions' 结尾的变量名来定义。

以下还有一些命名建议：

'...-hook'\
这个变量通常是一个普通的 hook

'...-function'\
这个变量的值是一个函数

'...-functions'\
这个变量的值是一个函数列表

'...-form’\
这个变量的值是一个表达式

'...-forms'\
这个变量的值是一个表达式列表

'...-predicate'\
这个变量的值是一个谓词函数

'...-flag'\
这个变量的值是布尔类型

'...-program'\
这个变量的值是程序名称

'...-command'\
这个变量的值是一整个shell命令

'...-switches'\
这个变量的值指明了命令的可选项

'prefix--...'\
这个变量主要在内部使用，而且定义在 prefix.el 文件内

'...-internal'\
这个变量主要在内部使用，而且定义在 C code 内

当你定义一个变量时，你需要思考你是否需要将其标记为安全变量（或者有风险的变量）;详情查阅文件局部变量。

当定义并初始化一个有复杂值的变量时（比如按键绑定），最好的方式是将整个求值过程放在 defvar 内部，比如：

```
(defvar my-mode-map
  (let ((map (make-sparse-keymap)))
    (define-key map "\C-c\C-a" my-command)
    ...
    map)
  docstring)
```

这个方法有几个好处，首先当加载文件时，如果用户推出，那么这个变量要么未完成初始化，要么已经正确的初始化了，而绝不会出现中间的状态。如果这个变量没有被初始化，那么重新加载这个文件，便可以让变量正确的初始化。其次，如果这个变量已经初始化了，那么重新加载文件并不会修改它；当用户已经运行过hook来改变一些配置（比如按键重新绑定）时，这个好处非常重要。最后，使用 C-M-x 运行 defvar 特殊式会完全重新初始化 map。

不过，将这个么多的代码放在 defvar 内有一个缺点：它会把 docstring 的位置拖后很多。这里有一个方法可以应对：

```
(defvar my-mode-map nil
  docstring)
(unless my-mode-map
  (let ((map (make-sparse-keymap)))
    (define-key-map "\C-c\C-a" 'my-command)
    ...
    (setq my-mode-map map)))
```

这样就和之前的方法有一样的优点，不过如果你想完全重新初始化变量，你要多按一次 C-M-x。
