Go文档示例函数必须命名为func ExampleXxx(),零参数零返回值,且Xxx需匹配导出标识符;函数体须调用fmt.Println输出,并以// Output:结尾声明期望输出,否则go test无法验证。

Example函数必须以Example开头且无参数无返回值
Go的godoc只会识别形如func ExampleXxx()的函数作为文档示例,且函数签名必须严格满足:零参数、零返回值。哪怕多一个int参数或加个error返回,godoc就直接忽略它,连编译都不报错,但网页上根本看不到这个例子。
常见错误现象:func ExampleParseInt(s string) { ... } —— 看似合理,实际不会出现在文档里;func ExampleWithTest() (bool, error) { ... } —— 同样静默失效。
- 函数名中的
Xxx部分建议对应被测函数名(如ExampleParseInt对应strconv.ParseInt),便于读者关联 - 如果想演示多个用法,用
ExampleXxx_1、ExampleXxx_2这种命名,godoc支持下划线分隔的后缀 - 函数体内部必须调用
fmt.Println(或fmt.Print/fmt.Printf)输出预期结果,否则示例会被认为“无输出”,go test运行时会报no example output
示例代码要能通过go test验证
go test默认会执行所有Example函数,并比对stdout是否与注释末尾的Output:块完全一致。这意味着示例不是“写给人看的说明”,而是可执行、可验证的测试用例。
使用场景:你改了MyFunc逻辑,顺手更新了ExampleMyFunc,go test立刻告诉你输出是否还匹配——这比纯文字文档靠谱得多。
立即学习“go语言免费学习笔记(深入)”;
- 必须在函数末尾添加
// Output:注释,后面紧接期望输出(空行也算输出的一部分) - 输出内容需逐字符匹配:换行、空格、制表符都不能错。例如
fmt.Println("hello")输出hello\n,// Output: hello就会失败,得写成// Output: hello\n或// Output: hello(godoc会自动归一化单个换行) - 避免在示例里做不可控操作:比如
time.Now()、rand.Int()、读文件、网络请求——它们让输出不可预测,go test必然失败
包级Example和类型/函数级Example的命名差异
包级示例(介绍整个包怎么用)函数名就是Example;给具体函数或类型写示例,则必须带上目标标识符,且大小写敏感。比如包叫bytes,想为Buffer类型写示例,得叫ExampleBuffer,不是ExampleBytesBuffer,也不是exampleBuffer。
容易踩的坑:IDE自动补全可能给你生成ExampleNewBuffer,但Buffer是类型名,不是函数名——只要godoc找不到同名导出标识符,这个例子就只显示不关联,用户点“Example”链接时看不到上下文高亮。
- 为导出函数写例:函数名是
TrimSpace→ 示例名ExampleTrimSpace - 为导出类型写例:类型名是
Scanner→ 示例名ExampleScanner - 为包本身写例:仅用
Example,且不能有下划线(Example_无效) - 非导出标识符无法绑定示例:比如
exampleHelper小写开头,ExampleHelper再规范也没用
Example里别用log.Fatal或os.Exit
示例函数本质是被go test调用的普通函数,一旦执行os.Exit(1)或log.Fatal,整个测试进程就退出,后续其他测试全部中断。这不是“示例失败”,是让go test崩溃。
性能影响不大,但开发体验极差:每次改错一个示例,就得重跑全部测试,还看不到其他失败信息。
- 用
if err != nil { fmt.Fprintln(os.Stderr, err); return }代替log.Fatal - 所有错误路径都应自然返回,让
go test自己判断输出是否匹配// Output: - 如果真需要模拟失败场景,用
fmt.Println("error: invalid input")显式打印,然后写进// Output:里
// Output:的换行处理,以及函数名与目标标识符之间那一点大小写和拼写一致性——看着像,godoc就不认。










