# 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。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://emacs-lisp.ivory.cafe/bian-liang/ding-yi-bian-liang-de-xiao-tie-shi.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
