1.高质量编程
1.1 简介
各种边界条件是否考虑完备
异常情况处理,稳定性保证
易读易维护
1.2 编码规范
代码格式
注释
注释应该解释代码作用
注释应该解释代码如何做的
注释应该解释代码实现的原因
注释应该解释代码什么情况会出错
包中声明的每个公共的符号:变量、常量、函数以及结构都需要添加注释
既不明显也不简短的公共功能必须予以注释
长度或复杂程度如何对库中的任何函数都必须进行注释
不需要注释实现接口的方法
命名规范
变量规范
简洁胜于冗长
缩略词全大写,但当其位于变量开头且不需要导出时,使用全小写
变量距离其被使用的地方越远,则需要携带越多的上下文信息
函数规范 函数名不携带包名的上下文信息,因为包名和函数名总是成对出现的 函数名尽量简短 当名为foo包某个函数返回类型Foo,可以省略类型信息而不导致歧义 当名为foo包某个函数返回类型T时(T并不是Foo,可以在函数名中加入类型信息
包规范
只由小写字母组成。不包含大写字母和下划线等字符
简短并包含一定的上下文信息。例如schema、task等
不要与标准库同名。例如不要使用sync或者strings
流程控制
优先处理错误情况/特殊情况,尽早返回或继续循环来减少嵌套
错误和异常处理
简单错误
优先使用error.New来创建匿名变量来直接表示简单错误
复杂错误
错误的Wrap实际上是提供了一个eror嵌套另一个error的能力,从而生成一个error的跟踪链
在fmt.Errorf中使用:%w关键字来将一个错误关联至错误链中
错误判定
判定一个错误是否为特定错误,使用errors.Is
在错误链上获取特定种类的错误,使用errors.As
panic
不建议在业务代码中使用panic
调用函数不包含recover会造成程序崩溃
若问题可以被屏蔽或解决,建议使用error代替panic
当程序启动阶段发生不可逆转的错误时可以在init或main函数中使用panic
recover
recover只能在被defer的函数中使用
嵌套无法生效
只在当前goroutine生效
defer的语句是后进先出
如果需要更多的上下文信息,可以recover后在log中记录当前的调用栈
1.3性能优化建议
1.3.1 性能优化建议-Benchmark
Go语言提供了支持基准性能测试的benchmark工具
1.3.2 性能优化建议-Silce,Map
slice预分配内存。尽可能在使用make()初始化切片时提供容量信息。可以减少底层的内存分配次数。 map也同样。
1.3.3 性能优化建议-字符串处理
使用+拼接性能最差,strings.Builder,bytes.Buffer相近,strings.Buffer更快
buf.Grow可以预分配内存
1.3.4 性能优化建议-空结构体
使用空结构体节省内存
1.3.5 性能优化建议-atomic包
使用atomic包
锁的实现是通过操作系统来实现,属于系统调用
atomic操作是通过硬件实现,效率比锁高
sync.Mutex应该用来保护一段逻辑,不仅仅用于保护一个变量
对于非数值操作,可以使用atomic.Value,能承载一个interface{}