Go代码风格与规范
Go语言以简洁、一致性和高效性著称,其官方规范(Go Code Review Comments)和工具链(如gofmt、go vet)是代码风格的核心依据。以下是关键要点:
一、格式化工具
-
gofmt
所有代码必须通过gofmt自动格式化(如缩进为Tab、运算符间距等)。这是Go社区的强制约定。gofmt -w your_file.go # 自动修复格式 -
goimports
自动管理包导入(增删未使用的包、按标准分组排序):goimports -w your_file.go
二、命名规范
-
变量/函数
- 驼峰式:
parseRequest(非parse_request) - 短命名优先:局部变量用
i、r等,但需确保可读性。 - 避免冗余:
UserService而非UserServiceInterface。
- 驼峰式:
-
包名
- 小写单数:
package http(非package httputils) - 避免通用名:如
util、common(改用具体功能命名)。
- 小写单数:
-
接口名
- 行为命名:
Reader(含Read()方法)、Stringer(含String())。
- 行为命名:
三、错误处理
-
显式检查
错误必须立即处理,禁止忽略:data, err := ioutil.ReadFile("file.txt") if err != nil { return fmt.Errorf("read file failed: %w", err) } -
错误包装
使用%w传递上下文(Go 1.13+):if err != nil { return fmt.Errorf("processing data: %w", err) }
四、代码结构
-
函数长度
单函数不超过一屏(约50行),过长时拆分为子函数。 -
方法接收器
- 值接收器(
func (u User) GetName()):适用于不可变类型。 - 指针接收器(
func (u *User) UpdateName()):需修改状态时使用。
- 值接收器(
-
包组织
- 按功能划分:如
/user包含model.go、service.go等。 - 避免循环依赖:通过接口解耦。
- 按功能划分:如
五、注释与文档
-
公共符号
所有导出函数、类型必须有//注释(生成godoc):// ParseRequest 解析HTTP请求至结构体 func ParseRequest(r *http.Request) (*Request, error) { ... } -
示例代码
用ExampleXXX()函数提供用例:func ExampleParseRequest() { req := ParseRequest(testRequest) fmt.Println(req) }
六、并发控制
-
Goroutine生命周期
确保能安全退出(通过context或done通道):go func(ctx context.Context) { select { case <-ctx.Done(): // 响应取消 return case data := <-ch: process(data) } }(ctx) -
同步原语
优先用sync.Mutex或sync.WaitGroup,避免裸atomic。
七、测试规范
-
测试文件命名
测试文件为xxx_test.go,如service_test.go。 -
表格驱动测试
用结构体切片组织多用例:func TestAdd(t *testing.T) { cases := []struct{ a, b, want int }{ {1, 2, 3}, {0, 0, 0}, } for _, c := range cases { if got := Add(c.a, c.b); got != c.want { t.Errorf("Add(%d,%d)=%d, want %d", c.a, c.b, got, c.want) } } }
八、其他最佳实践
- 避免全局变量:通过依赖注入传递状态。
- 零值可用:如
sync.Mutex无需显式初始化。 - 避免
init()函数:易导致隐式依赖,改用显式初始化。
提示:用
golangci-lint集成检查工具,自动执行上述规范。

被折叠的 条评论
为什么被折叠?



