Go语言开发规范
Go 语言由于其高性能的特性,一般在服务器端使用。比如 Linux 资源管理,分布式计算等。开发规范强调代码简洁、易读、并且有良好的风格一致性。
1. 代码风格
- 缩进: 使用 tabs(而不是 spaces)进行代码缩进。
- 行宽: 代码行尽量不要超过 80 个字符。
- 空行: 合理使用空行来分隔不同功能块或函数。
- 命名规范:
- 使用 驼峰命名法(camelCase)来命名变量、函数和字段名。
- 使用 PascalCase(大驼峰)来命名类型、结构体(struct)、接口(interface)等。
- 常量使用大写字母与下划线(UPPER_CASE)进行命名。
- 避免使用单字母命名,除非是非常常见的(例如:
i
,j
,k
在循环中)。 - 保持命名简洁明了,避免不必要的缩写。
2. 文件和目录结构
- 主程序入口: 应将
main
包放在项目的根目录中,并且保持其尽量简单。 - 目录结构: 可以使用如下的结构来组织项目:
/cmd - 主程序 /pkg - 可重用的库 /internal - 私有库,不能被外部引用 /api - 接口定义 /web - 网页、模板等资源 /scripts - 脚本文件 /docs - 文档
- 每个包的职责单一: 每个包只处理一个特定的任务,不要让一个包承担过多的功能。
3. 错误处理
- Go 没有异常机制,错误处理依赖于
error
类型。- 函数返回错误时,通常需要显式检查错误。
- 处理错误时尽量提供清晰的错误信息,以便于调试。
- 错误检查的惯例是:
result, err := someFunction() if err != nil { log.Fatal(err) // 或者返回错误 }
4. 并发编程
- goroutine: 用来实现并发的基本单元。使用时要注意避免 goroutine 泄漏。
- channel: 用来在 goroutine 之间传递数据,推荐使用具名的 channel 类型来提高代码可读性。
- select 语句: 用于选择多个 channel 操作,避免阻塞。
- 保持共享数据的同步性,尽量避免直接共享内存,使用通道(channel)进行通信。
5. 接口和类型
- 接口(interface):
- Go 语言的接口是隐式实现的,即不需要显式声明一个类型实现了某个接口。
- 接口的设计应保持精简和聚焦。
- 接口方法尽量不要带有实现,避免不必要的耦合。
- 结构体(struct):
- 使用结构体时,字段最好使用导出字段(大写字母开头)。
- 如果一个结构体有多个字段,使用行内注释来描述字段的作用。
- 如果结构体字段有默认值,可以通过构造函数来初始化。
6. 文档和注释
- 文档注释:函数、类型、方法和包应有清晰的文档注释,注释应该是完整的句子,并且描述其作用。
- 函数和方法注释:函数的注释应直接位于函数声明前。
// CalculateSum computes the sum of two integers. func CalculateSum(a, b int) int { return a + b }
7. 包管理
- 使用 Go modules 来管理包依赖。避免使用
GOPATH
,将项目与外部包的管理交给 Go modules。- 使用
go mod init
创建一个模块。 - 使用
go mod tidy
清理未使用的依赖。 - 使用
go get
安装外部依赖。
- 使用
8. 性能和优化
- 避免不必要的内存分配:使用
sync.Pool
来重用对象,避免频繁的内存分配。 - 延迟加载:在需要时再加载资源而不是提前加载。
- 性能测试:通过
testing
包进行性能测试,使用go test -bench
来测试性能。
9. 单元测试
- Go 提供了
testing
包来编写单元测试。- 测试函数名通常以
Test
开头。 - 编写清晰的测试,检查边界条件和常规情况。
- 使用
go test
运行测试。
- 测试函数名通常以
10. 依赖注入
Go 语言中并没有内建的依赖注入框架。通常,依赖注入通过构造函数进行:
type Service struct { repo Repository } func NewService(r Repository) *Service { return &Service{repo: r} }