Go Style 代码风格规范

Golang 代码 编程规范

Go 代码应该以最简单的方式编写,以实现其目标,无论是在行为还是性能方面。在 Google Go 代码库中,简单代码:

  • 从上到下都易于阅读;
  • 不假设你已经知道它在做什么;
  • 不假设你可以记住所有前面的代码;
  • 没有不必要的抽象层次;
  • 没有能引起关注的世俗名称;
  • 让开发者清楚地了解价值观和决策的传播;
  • 有注释解释代码为什么这样做,而不是做什么,以避免将来出现偏差;
  • 有独立的文档;
  • 有 有用的错误和有用的失败测试;
  • 可能经常与"聪明"的代码互相排斥。

参考指南:

1. gofmt 统一代码格式

执行 go fmt ./... 来统一代码格式。

2. 注释说明增强

在会引发歧义或者和上文判断不同时使用注释以提醒开发者。

golang 复制代码
if err := doSomething(); err != nil {
    // ...
}

if err := doSomething(); err == nil { // if NO error
    // ...
}
3. 注释应该说明的是"为什么",而不是"做什么"
go 复制代码
// ❌ Bad
// Increment i by 1
i = i + 1

// ✅ Good
// Retry count is increased after each failed attempt.
i++
4. 当有 context.Context 参数时,其永远是方法的第一个参数并且不被放在结构体中
golang 复制代码
// ❌ Bad
type ServerContext struct {
  ctx context.Context
  // other 
}

func (s *ServerContext) doSomething(param any, ctx context.Context) {
  // ...
}

// ✅ Good
type ServerContext struct {
  // other 
}

func (s *ServerContext) doSomething(ctx context.Context, param any) {
  // ...
}
5. 正确声明变量
golang 复制代码
// ❌ Bad
// nil 
s := []int8{}

// ✅ Good
// 非零但长度为零
var s []int

i := 42

\]T{} 会默认分配内存,var s \[\]T 更清晰与高效。 在使用非零值初始化时,使用 `:=` 赋值。 ##### 6. 代码中不要出现 panic ```golang // ❌ Bad func ParseConfig(file *os.File, cfg any) { decoder := yaml.NewDecoder(file) if err := decoder.Decode(cfg); err != nil { panic("failed to decode config: " + err.Error()) } } // ✅ Good func Parse(file *os.File, cfg any) error { decoder := yaml.NewDecoder(file) if err := decoder.Decode(cfg); err != nil { return err } return nil } ``` 依赖库应该优先返回 err,而不是终止程序。 ##### 7. 保持错误信息干净,使用结构化日志 ```golang // ❌ Bad return fmt.Errorf("some error.") // ✅ Good return fmt.Errorf("some error.") ``` error msg 小写开头且不以任何标点结尾。 ##### 8. 避免多余的 else 逻辑 ```golang // ❌ Bad if err != nil { if something { return err } } else { doSomething() } // ✅ Good if err != nil { return err } doSomething() ``` 尽早返回 error 且避免多余的 else 语句。 ##### 9. 使用包别名导入 除非为了避免名称冲突,否则应避免重命名导入;好的包名称不应该需要重命名。如果发生冲突,优先重命名本地或项目特定的导入。 import pkg 按组组织,每组之间以空行分隔。标准库包始终位于第一组,其次是第三方包,最后是项目内部包。 ##### 10. 缩写保持大写和官方库一致 ```golang // ❌ Bad type HttpServer struct{} // ✅ Good type HTTPServer struct{} ``` 标准库写法:HTTP、ID、JSON。保持一致性. ##### 11. 避免裸返回 ```golang // ❌ Bad func sum(a, b int) (result int) { result = a + b return } // ✅ Good func sum(a, b int) int { return a + b } ``` 除非函数非常短,一眼看到底时使用裸返回。 ##### 12. 包名、接受者名保持简单与简洁切避免函数名重复与啰嗦 ```golang // ❌ Bad package my_utils func (this *Server) Start() {} package yamlconfig func ParseYAMLConfig(input string) (*Config, error) func OverrideFirstWithSecond(dest, source *Config) error // 不应书写函数的返回参数名,这会导致 goDoc 混乱 func doSomething(a, b int) (sum int, err error) { // logic } // ✅ Good package utils func (s *Server) Start() package yamlconfig func Parse(input string) (*Config, error) func Override(dest, source *Config) error func doSomething(a, b int) (int,error) { // logic } ``` * 包名小写、简洁、无下划线; * 接受者变量 `s`, `r`, `c` 这种短变量常见且清晰; * 包名提供上下文。 当需要消除类似名称的函数歧义时,可以包含额外的信息。 ```golang // ✅ Good func (c *Config) WriteTextTo(w io.Writer) (int64, error) func (c *Config) WriteBinaryTo(w io.Writer) (int64, error) ``` ##### 13. 函数名中不应出现返回类型且命名体现语义 ```golang // ❌ Bad func TransformToJSON(input *Config) *jsonconfig.Config func (c *Config) GetJobName(key string) (value string, ok bool) // ✅ Good func Transform(input *Config) *jsonconfig.Config // 返回值函数中不要动词 func (c *Config) JobName(key string) (value string, ok bool) // 动作用动词,取值用名词 func (c *Config) ApplyChanges() error func ProcessData(data []byte) error ``` 动作用动词,取值用名词且返回值函数中不要动词。 ##### 14. 测试写法符合 Go `got %v, want %v`风格 ```golang // ❌ Bad if got != want { t.Errorf("expected %v but got %v", want, got) } // ✅ Good if got != want { t.Errorf("got %v, want %v", got, want) } ``` ##### 15. 常量与结构化错误声明 ```golang type Animal string var ( // ErrDuplicate occurs if this animal has already been seen. ErrDuplicate = errors.New("duplicate") // ErrMarsupial occurs because we're allergic to marsupials outside Australia. // Sorry. ErrMarsupial = errors.New("marsupials are not supported") ) func process(animal Animal) error { switch { case seen[animal]: return ErrDuplicate case marsupial(animal): return ErrMarsupial } seen[animal] = true // ... return nil } ``` 在使用到常量定义或者错误时,将其机构化定义在文件顶部或统一管理。 ##### 16. 当函数参数列表过多时,使用可变参数处理输入 ```golang type SshProtocol struct { Host string Port string Timeout string Username string Password string PrivateKey string PrivateKeyPassphrase string ReuseConnection string Script string ParseType string ProxyHost string ProxyPort string ProxyUsername string ProxyPassword string UseProxy string ProxyPrivateKey string } type SshProtocolConfigOptFunc func(option *SshProtocol) func NewSshProtocol(host, port string, opts ...SshProtocolConfigOptFunc) *SshProtocol { option := &SshProtocol{ Host: host, Port: port, } for _, opt := range opts { opt(option) } return &SshProtocol{ Host: host, Port: port, Timeout: option.Timeout, Username: option.Username, Password: option.Password, PrivateKey: option.PrivateKey, PrivateKeyPassphrase: option.PrivateKeyPassphrase, ReuseConnection: option.ReuseConnection, Script: option.Script, ParseType: option.ParseType, ProxyHost: option.ProxyHost, ProxyPort: option.ProxyPort, ProxyUsername: option.ProxyUsername, ProxyPassword: option.ProxyPassword, UseProxy: option.UseProxy, ProxyPrivateKey: option.ProxyPrivateKey, } } func (sp *SshProtocol) IsInvalid() error { return nil } ``` ##### 17. 字符串拼接 ```golang // 连接少量字符时使用 + key := "projectid: " + p // 构建带有格式化的复杂字符串时,优先使用 fmt.Sprintf str := fmt.Sprintf("%s [%s:%d]-> %s", src, qos, mtu, dst) // 字符串格式更加复杂时,优先使用 text/template 或 safehtml/template ```

相关推荐
小码哥_常7 小时前
Spring Boot 牵手Spring AI,玩转DeepSeek大模型
后端
0xDevNull7 小时前
Java反射机制深度解析:从原理到实战
java·开发语言·后端
小小亮017 小时前
Next.js基础
开发语言·前端·javascript
华洛7 小时前
我用AI做了一个48秒的真人精品漫剧,不难也不贵
前端·javascript·后端
ALex_zry7 小时前
C++网络编程心跳机制与连接保活:长连接稳定性保障
开发语言·网络·c++
WZTTMoon7 小时前
Spring Boot 中Servlet、Filter、Listener 四种注册方式全解析
spring boot·后端·servlet
standovon8 小时前
Spring Boot整合Redisson的两种方式
java·spring boot·后端
Amumu121388 小时前
Js:正则表达式(二)
开发语言·javascript·正则表达式
Sgf2278 小时前
ES8(ES2017)新特性完整指南
开发语言·javascript·ecmascript
Cosolar8 小时前
LlamaIndex RAG 本地部署+API服务,快速搭建一个知识库检索助手
后端·openai·ai编程