Go注释是可执行文档的源码组成部分,需严格遵循格式:函数注释紧贴声明上方用//、结构体字段逐行注释、包注释唯一且以“// Package xxx”开头;空行、块注释或拼写错误均导致文档丢失或失效。

Go 的注释不是“写给人看的补充说明”,而是直接参与构建可执行文档的源码组成部分;go doc 和 godoc(或 go doc -http=:6060)能直接解析它,所以格式错一个字母,生成的文档就可能丢失签名、参数或根本无法识别。
函数/方法注释必须紧贴声明上方且用 // 单行注释
Go 不识别 /* */ 块注释作为文档注释,也不接受空行隔开。哪怕只多一个空行,go doc 就会跳过该函数。
正确写法:
// Add returns the sum of a and b.
func Add(a, b int) int {
return a + b
}
常见错误:
立即学习“go语言免费学习笔记(深入)”;
- 在
// Add...前加空行 → 文档丢失 - 用
/* Add... */包裹 →go doc完全忽略 - 注释末尾带句号但前面没空格,如
// Add... .→ 会被当成句子结尾,影响后续解析(尤其含代码示例时)
结构体字段注释要逐行写,不能合并或省略
字段注释不被 go doc 当作结构体文档的一部分,但会被 IDE(如 VS Code + gopls)用于悬停提示,且影响 go vet 对未导出字段的检查。
导出字段必须有注释,否则 go lint(或 golint 已弃用,推荐 revive)会报 exported field X should have comment。
正确写法:
// User represents a registered account.
type User struct {
// ID is the unique identifier generated by the system.
ID int `json:"id"`
// Name is the display name, max 50 chars.
Name string `json:"name"`
}
注意点:
- 每个字段前都要有独立的
//行,不能写成// ID ... // Name ...合并在一行 - 字段名首字母大写(导出)才需注释;小写字段即使有注释也不会出现在
go doc输出中 - 结构体注释和字段注释之间可以有空行,但字段之间不能空行(否则后一个字段注释会被视为上个字段的延续)
包级注释必须放在 package xxx 上方,且仅允许一个
包注释是整个包的门面,go doc 显示包首页时只取这个注释。如果写了多个,只有最上面那个生效;如果写在 package 下方,会被完全忽略。
正确位置:
// Package auth provides JWT-based user authentication and token refresh logic. // It depends on github.com/golang-jwt/jwt/v5 and requires a Redis client for blacklisting. package auth
关键限制:
- 必须以
// Package xxx开头(xxx是包名),否则go doc不认为这是包注释 - 只能有一段,不能拆成两块
// Package...+// This package... - 支持简单 Markdown(如
`code`、**bold**),但不支持列表或标题 —— 渲染时会被转义为纯文本
命令行工具和测试文件默认不生成文档,需手动指定
go doc 默认只处理 package main 中导出的标识符,而命令行程序(main.go)通常没有导出函数,结果就是 go doc ./cmd/mytool 返回空。测试文件(*_test.go)同理被跳过。
解决方式:
- 想让
main包可文档化:把核心逻辑抽到独立包(如pkg/cli),main只做入口调用 - 临时查看测试函数文档:用
go doc -all ./path/to/pkg,其中-all强制包含非导出项(但测试函数本身仍不会显示,除非它被导出) - 生成完整站点时,
go doc -http=:6060会列出所有包,但main和*_test.go仍不可见 —— 这不是 bug,是设计使然
真正容易被忽略的是:包注释里写的依赖、环境变量、配置路径这些信息,一旦拼写错误(比如把 REDIS_URL 写成 REDIST_URL),用户照着文档配就必然失败——而这种错误 go vet 或 staticcheck 都不会捕获。



















