Go开发规范 | 青训营笔记

104 阅读2分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的第3篇笔记。

编码规范

注释

  • 代码是最好的注释
  • 提供代码未表达出的上下文信息

命名规范

变量名

  • 简洁胜于冗长
  • 使用驼峰命名法,不要使用下划线
  • 缩略词全大写,但当其位于变量开头且不需要导出时,使用全小写
  • 变量距离其被使用的地方越远,则需要携带越多的上下文信息
for i := 0; i < len(s); i++ {
    //todo
}

无需使用index,index的额外冗长没有增加对于程序的理解。

func (c *Client) send(req *Request, deadline time.Time) {
    //todo
}

t常代指任意时间,deadline有特殊含义,替换成t降低了变量名的信息量。

函数名

  • 函数名不携带包名的上下文信息,因为包名和函数名总是成对出现
  • 函数名尽量简短
  • 可以在函数名中体现出函数返回类型

包名

  • 只由小写字母组成。不包含下划线等字符
  • 简短并包含一定的上下文信息
  • 不要与标准库同名。例如sync、strings等。
  • 尽量不使用常用变量名作为包名
  • 尽量使用单数而不是复数
  • 谨慎使用缩写

控制流程

  • 线性原理,处理逻辑尽量走直线,避免逻辑嵌套
  • 尽量保证正常代码的路径为最小缩进,特殊情况提前返回
  • 故障问题大多出现在复杂的条件语句和循环语句中

错误和异常处理

  • error,尽可能提供简明的上下文信息,方便定位问题
  • panic,用于真正异常的情况
  • recover,只能在defer中被使用,嵌套无法生效,只在当前goroutine生效

不建议使用panic,调用函数不包含recover函数会造成程序崩溃。

defer采用栈结构存储的,后进先出策略。

GORM使用规范

包管理

model层下,对于每一个table使用一个文件进行管理,例如

// student.go
type student struct {
    id   uint
    name string 
    ...
}

func ...{ // student表对应的方法
}

命名规范

使用TableName方法来指定表和结构体的关系

func (student) TableName() string {
  return "student"
}
  • 对于查询类方法,使用QueryXXX
  • 对于更新类方法,使用UpdateXXX
  • 对于删除类方法,使用DeleteXXX
  • 对于创建类方法,使用CreateXXX