godoc包注释必须顶格写在package前且无空行,否则文档消失;导出标识符Doc注释须紧贴声明、首句完整并以名称开头;Deprecated注释需单行顶格、大小写准确;字段注释要具体到业务约束。

godoc 要求包注释必须顶格写在 package 前且无空行
不满足这条,整个包文档在终端、VS Code 悬停、go doc 命令里都会消失。很多人写了注释却看不到效果,问题就卡在这儿。
包注释不是可选的装饰,而是 godoc 工具链的硬性入口点——它必须是文件中第一个非空、非注释块,且与 package 之间**绝对不能有空行**。
- // Package utils 提供字符串和时间工具函数。 // // 注意:所有函数返回新值,不修改输入。 package utils ✅
- // utils 工具包 func Foo() {} <p>package utils ❌(
<p>是空行等效,godoc 直接跳过) - /* Package utils ... */ package utils ❌(godoc 只认
//行注释)
一个包只需在一个 .go 文件里写包注释,其他文件留空即可;多写不会叠加,反而可能因格式不一致导致解析失败。
导出标识符的 Doc 注释必须紧贴声明上方、无空行
函数、结构体、常量、变量等首字母大写的导出项,若希望出现在文档里,注释必须像胶水一样粘在声明前——中间插一个空行、一个 var、甚至一个 import,gopls 就不识别。
立即学习“go语言免费学习笔记(深入)”;
首句必须是完整句子,以被注释项名开头,结尾带句号。这不是风格建议,是 godoc 解析器的分句依据。
- // TrimSpaceLeft 移除字符串左侧空白字符。 // // 支持 \t\r\n 和 Unicode 空白(U+0085、U+2000–U+200A)。 func TrimSpaceLeft(s string) string { ... } ✅
- // TrimSpaceLeft 移除左侧空白 // // 支持多种空白符。 <p>func TrimSpaceLeft(s string) string { ... } ❌(空行导致后续说明被截断)
- // trimSpaceLeft 移除左侧空白。 func trimSpaceLeft(s string) string { ... } ❌(小写名不导出,注释不进 godoc)
参数和返回值说明用 // - s: 这类格式是社区习惯,godoc 不解析,但 IDE 悬停会原样显示,建议保持简洁统一。
// Deprecated: 注释必须顶格、单行、冒号后空一格
IDE 标灰、悬停提示“已弃用”,只在满足三个条件时触发:注释块里有且仅有一行以 Deprecated: 开头(注意大小写和冒号)、该注释属于导出标识符、且与标识符之间无空行。
- // Deprecated: Use NewClient instead. // This function will be removed in v2.0. func NewHTTPClient() *Client { ... } ✅
- // deprecated: Use NewClient instead. func NewHTTPClient() *Client { ... } ❌(小写 d,gopls 忽略)
- // Deprecated: Use NewClient instead. // v2.0 removed. func NewHTTPClient() *Client { ... } ❌(两行都含
Deprecated:,部分 gopls 版本拒绝渲染)
类型弃用更危险:如果 type User struct 被标记为 deprecated,但已有 JSON 字段或方法被外部调用,删掉它会直接破坏兼容性。此时应保留结构体,仅弃用构造函数或提供别名迁移路径。
结构体字段注释要具体到业务约束,而非泛泛而谈
导出结构体的每个导出字段都必须注释,因为它们直接影响 API 文档、JSON 序列化行为、校验逻辑。模糊注释如 // email 几乎没用,调用方仍需翻源码确认是否必填、格式要求、长度限制。
- // Email is the user's primary contact address. Required. json:"email" validate:"required,email" ✅
- // Name is the full name, max 100 chars, ASCII only. ✅
- // user name ❌(信息不足,无法生成有效文档或校验)
- // Name string `json:"name"` ❌(把 tag 当注释,godoc 不提取 tag 内容)
未导出字段(小写开头)的注释不会进入 godoc,但可在代码内用 // 行注释解释并发安全假设、缓存策略或边界条件——重点讲清“为什么这么设计”,而不是重复字段名。
真正难的不是写注释,是让注释和代码保持同步。一个字段语义变了但注释没改,比没注释更危险;一个函数加了新约束但 Doc 没更新,调用方按旧文档用就可能 panic。注释不是写完就扔的说明书,它是接口契约的文本化延伸,得跟代码一起测试、一起 review、一起上线。


















