这是我参与「第三届青训营 -后端场」笔记创作活动的的第2篇笔记
编码规范
注释
- 代码是最好的注释
- 注释应该提供代码为表达出的上下文信息
命名规范
variable
- 简介胜于冗长
- 缩略词全大写,例:ServeHTTP
- 变量距离其被使用的地方越远,则需要携带越多的上下文信息
- 全局变量需要在名字中展示跟多的上下文信息,使得在不同地方可以轻易辨认其含义
function
- 函数名不携带包名信息,包名和函数名成对出现
- 函数名尽量短
- 包名和函数返回类型一直,可以省略类型信息,反之,需要加上类型信息
package
- 只有小写字母组成
- 简短,包含一定上下文信息
- 不与标准库同名
- 不使用关键字做包名
核心目标时间的阅读代码成本,重点考虑上下文信息
流程控制
尽量保持最小缩进
优先处理错误情况,尽量返回或继续循环来减少嵌套,即减少循环层数。
小结
- 线性原理,减少嵌套
- 正常流程代码沿屏幕向下移动
- 替身代码可读性
- 故障大多在复杂语句和循环中
简单错误
即仅出现一次的错误,优先使用errors.New来创建匿名变量来表示简单错误,使用fmt.Errorf来格式化。
错误和异常处理
Wrap 和Unwrap
- 错误的Wrap是一个error嵌套,形成错误链
- 在Errorf中,%w关键字来关联错误链
错误判断
errors.ls判断是否是特定错误
errors.As获取特定错误
panic
不建议在业务中使用panic,建议使用error。
可以在init或main中暴露不可逆错误
recover
只能在defer的函数中使用
无法嵌套
只在当前goroutine()生效
defer的语句是栈式执行
性能优化
benchmark性能测试工具
slice
尽可能在出使用指定容量,减少扩容次数。
slice本质是数组片段
- 包括数组指针
- 片段长度
- 片段容量(未进行扩容前)
- 切片操作不会复制切片指向的元素
- 创建一个新的切片回复用原来切片的底层数组
陷阱--大内存未释放
在大切片上创建小切片,会导致大切片被引用,无法释放大内存
可以使用copy替代re-slice,则不会引用大切片
map
建议与分配内存,减少扩容和rehash
strings.Builder
与Java的可变字符串一样。
go中的字符串是不可变的,每次+都会创建新的字符串,使用可变字符串可以减少创建新字符串的次数,替身效率。
空结构体
用来占位,节省内存。
atomic
- 锁通过操作系统来实现,属于系统调用
- atomic操作通过硬件实现,效率比锁高
- sync.Mutex应该用来保护一段逻辑,不仅仅是一个变量,即粒适中
- 对于非数值操作,可以使用atomic.Value,承载一个interface{}