这是我参与「第三届青训营 -后端场」笔记创作活动的第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