← 返回
后端开发 2026.03.06

Go资深工程师讲解(慕课) 007_godoc与代码生成

后端开发

对应视频 8-6 生成文档和示例代码

1. godoc 文档生成

Go 的文档直接从源码注释中提取,不需要特殊标记语法。

1.1 注释规范

// Package queue 实现了一个简单的 FIFO 队列。
//
// 该队列基于切片实现,支持 Push、Pop 和 IsEmpty 操作。
package queue

// Queue 代表一个整数先进先出队列。
type Queue []int

// Push 将元素 v 添加到队列尾部。
func (q *Queue) Push(v int) {
    *q = append(*q, v)
}

// Pop 移除并返回队列头部的元素。
// 如果队列为空,会 panic。
func (q *Queue) Pop() int {
    head := (*q)[0]
    *q = (*q)[1:]
    return head
}

// IsEmpty 返回队列是否为空。
func (q *Queue) IsEmpty() bool {
    return len(*q) == 0
}

规则: - 注释紧贴在声明上方,以被注释对象的名称开头 - 包注释写在 package 语句上方(或单独的 doc.go 文件中) - 空行分隔段落 - 缩进的文本会被当作代码块显示

1.2 查看文档

# 本地启动 godoc 服务(Go 1.12 之前内置,之后需安装)
go install golang.org/x/tools/cmd/godoc@latest
godoc -http :6060
# 浏览器访问 http://localhost:6060

# 命令行查看
go doc fmt
go doc fmt.Println
go doc -all queue       # 查看包的所有文档

1.3 pkg.go.dev

发布到 GitHub 的包会自动在 pkg.go.dev 上生成文档,无需额外操作。

2. Example 测试(可执行的文档)

Example 函数既是文档又是测试,写在 _test.go 文件中:

// queue_test.go
package queue_test

import (
    "fmt"
    "myproject/queue"
)

// 包级别的示例
func Example() {
    q := queue.Queue{1}
    q.Push(2)
    q.Push(3)
    fmt.Println(q.Pop())
    fmt.Println(q.Pop())
    fmt.Println(q.IsEmpty())
    // Output:
    // 1
    // 2
    // false
}

// 方法级别的示例
func ExampleQueue_Push() {
    var q queue.Queue
    q.Push(1)
    q.Push(2)
    fmt.Println(q)
    // Output:
    // [1 2]
}

func ExampleQueue_IsEmpty() {
    var q queue.Queue
    fmt.Println(q.IsEmpty())
    q.Push(1)
    fmt.Println(q.IsEmpty())
    // Output:
    // true
    // false
}

命名规则

示例类型函数名
包示例Example()
函数示例ExampleFuncName()
类型示例ExampleTypeName()
方法示例ExampleTypeName_MethodName()
多个示例ExampleTypeName_MethodName_suffix()

Output 注释

  • // Output: — 精确匹配输出
  • // Unordered output: — 不关心输出顺序(适合 map 遍历等)
  • 没有 Output 注释 → 只编译不运行(仅检查编译通过)
# 运行示例测试
go test -v -run Example

运行 godoc 时,Example 函数会自动显示在对应函数/类型的文档页面中,并且带有可运行按钮。

3. go generate

go generate 用于在编译前运行代码生成工具。

3.1 基本用法

在 Go 源文件中添加特殊注释:

//go:generate stringer -type=Pill
package painkiller

type Pill int

const (
    Placebo Pill = iota
    Aspirin
    Ibuprofen
    Paracetamol
)
# 安装 stringer 工具
go install golang.org/x/tools/cmd/stringer@latest

# 运行 generate(会执行文件中所有 //go:generate 指令)
go generate ./...

这会自动生成 pill_string.go,包含 Pill 类型的 String() 方法。

3.2 常见的 generate 用途

工具用途
stringer为枚举类型生成 String() 方法
mockgen生成接口的 mock 实现
protoc从 .proto 文件生成 Go 代码
sqlc从 SQL 生成类型安全的 Go 代码
enumer枚举生成(比 stringer 更强)
go-bindata将静态资源嵌入二进制

3.3 Go 1.16+ embed(替代 go-bindata)

package main

import (
    "embed"
    "fmt"
    "net/http"
)

//go:embed static/*
var staticFiles embed.FS

//go:embed config.json
var config []byte

//go:embed version.txt
var version string

func main() {
    fmt.Println("Version:", version)
    fmt.Println("Config:", string(config))

    // 静态文件服务
    http.Handle("/static/",
        http.FileServer(http.FS(staticFiles)))
    http.ListenAndServe(":8080", nil)
}

4. 总结

特性说明
注释即文档紧贴声明上方的注释自动成为文档
Example 测试既是可运行的文档,又是测试用例
go doc命令行查看文档
godoc -http本地 Web 文档服务
pkg.go.dev公开包的在线文档
go generate编译前的代码生成
//go:embed嵌入静态资源到二进制(Go 1.16+)