Skip to content
This repository has been archived by the owner on Aug 24, 2022. It is now read-only.

Rules of godoc documenting

YU HengChun edited this page Mar 25, 2015 · 8 revisions

基本规则

Go 团队给出一种在 .go 源码中书写文档的方法. 其基本规则很简单

  1. 代码上方一段无空行间隔的注释被提取到文档.
  2. 行尾注释被原样提取到文档
  3. 其它被文档忽略.
package demo

// 这句注释不会被提取到文档

// 这是 MyFunc 的注释文档
func MyFunc() {
    // 函数主体代码不会被提取
}

type MyType struct {
    // 此行注释属于 Name 的注释, 当然被提取
    Name string // 导出定义的尾注释被原样提取
}

工具

Go 团队提供了一些 package 对文档进行支持.

  1. go/doc 访问 Go AST 中的文档以及 ToHTML, ToText, Note.
  2. tools/godoc 更多的文档支持功能, 未来会被拆分.
  3. cmd/godoc 命令行工具, 生成 (渲染) 文档到其它格式.

渲染

基本规则没有约定渲染后的样子, 上述工具的行为成为事实上的标准. 这里列举一些已知规则:

  1. .go 文件名排序后的顺序提取注释文档.
  2. 所有 package name 语句的注释会被提前合并到文档前部.
  3. 块声明在文档中仍呈现块状.
  4. 注释中的空行, 缩进和首字母大写影响渲染结果

段落与换行

由源码中的空行分割的文本块形成段落. 段落中的空行被保留

源码中的非空行换行只是为了便于阅读, 空行注释是段落中的换行. 示例:

// 第一个段落, 虽然只有一行

// 上面有空行, 形成第二个段落.
// 这个换行会被重新整理, 合并到前行尾部.
//
// 上面有个空行注释, 它会被保留. 这四行属于一个段落.

/*
单行块注释, 这是第三个段落
*/

/*
多行块注释, 这是第四个段落
这个换行会被重新整理, 合并到前行尾部.

上面有个空行注释, 它会被保留. 这四行属于一个段落.
*/

/*
这里展示单行(独立行)注释.

这是个单行注释. 只有一行, 上下都有空行注释.

后续注释...
*/

注释组

首先注释组 CommentGroup 是 Go AST 中的概念, 连续的注释(块)被定义为一个注释组. 该注释组的全部注释代表某 Go 实体定义的注释.

/*
MyFunc 第一段注释.
*/
// MyFunc 第二段注释.
func MyFunc(){}

注意和第一段之间没有空行也没有其它 Go 实体定义.

这是两段注释, 会合并为一个注释组, 合并的注释作为 MyFunc 的注释. 下面写法有相同的渲染效果.

// MyFunc 第一段注释.
//
// MyFunc 第二段注释.
func MyFunc(){}

不同的是第二种注释写法在 AST 就是一个注释对象, 而不是注释组. 查看 play CommentGroup, 源码第 23-33 行对应输出的第 15-55 行.

缩进

缩进是指段落行首有空格或者 \t. 首行注释缩进量被认为是作者书写习惯, 段落被重新整理, 逐行剔除这个缩进量. 整理后, 段落中的连续缩进行( 肯定不包括第一行)被原格式保留(不受行宽限制). 示例:

//        单行的前缩进会被剔除, 因为单行也就是首行.

//    多行的首行前缩进会当作习惯缩进量, 段落被重整.
//         来一行再次缩进的
//    来一行同缩进量的

上面的写法整理后和下面写法是一样效果

// 单行的前缩进会被剔除, 因为单行也就是首行.

// 多行的首行前缩进会当作习惯缩进量, 段落被重整.
//      来一行再次缩进的
// 来一行同缩进量的

行宽限制

段落内的一行限制在 80 个字符, 未超出会合并后续文本, 超出会被加入换行.

单行首字大写

段落中单行注释(无标点符号, 运算符号等)中首字大写会被区别显示, 在 HTML 中以 <h3> 标签包裹. 示例:

// Nop, 虽然这行首字大写, 但这是首行, 不属于单行注释.
//
// Nop, 虽然这行首字大写, 但含有标点符号.
//
// Yes 此行在 HTML 渲染中会被 h3 包裹 注意此行没有多余的符号
//
// Nop 上一行已经被区别显示了 此行不会被 h3 包裹

保留换行代码

有时候因习惯或者代码过长, 作者会手工加入换行, 这些换行被保留. 示例:

func (f HandlerFunc) ServeHTTP(w http.ResponseWriter,
    r *http.Request) { // 这个换行是合法的, 并被保留
}

Note

Note 在注释中的某行以形如 "MARKER(uid): note body" 的格式出现. 其中 MARKER 是纯大写字母组成的字符串, MARKER 其实是 coder 自定义的, 其含义和如何使用是文档工具负责的. uid 至少为一个字符. note body 可以分多行, 只要每行加缩进就行, 空行或者无缩进表示结束. go/doc 工具支持提取所有的 Note 到 Package.Notes, 但未申明如何使用. 常见的 'MARKER` 有: "NOTE", "TODO", "BUG", "TIP".

Synopsis

Synopsis 方法返回一段文本的第一句话, 这就是概要(或者叫简介). 如果文本以 IllegalPrefixes 中的字符串开头, 返回 "". 这对文档生成非常有用, 也需要写文档时注意 IllegalPrefixes 中的字符串有特殊含义. go 中的一句话包简介就是这么来的.