这是我参与「第五届青训营」伴学笔记创作活动的第 3 天
高质量编程
编码规范
代码格式
使用gofmt格式化
注释
注释应该做的:
- 注释应该解释代码作用
- 注释应该解释代码如何做的
- 注释应该解释代码实现的原因
- 注释应该解释代码什么情况会出错
好的代码有很多注释,坏的代码需要很多注释
命名规范
变量
- 简洁胜于冗长
- 缩略词全大写,但当其位于变量开头且不需要导出时,使用全小写
- 例如使用ServeHTTP而不是ServeHttp
- 使用XMLHTTPRequest或者xmlHTTPRequest
- 变量距离其被使用的地方越远,则需要携带越多的上下文信息
- 全局变量在其名字中需要更多的上下文信息,使得在不同地方可以轻易辨认出其含义
函数
- 函数名不携带包名的上下文信息,因为包名和函数名总是成对出现的
- 函数名尽量简短
- 当名为foo 的包某个函数返回类型Foo时,可以省略类型信息而不导致歧义
- 当名为foo的包某个函数返回类型T时(T并不是Foo),可以在函数名中加入类型信息
Good naming is like a good joke. If you have to explain it, it' S not funny
控制流程
线性原理,处理逻辑尽量走直线,避免复杂的嵌套分支
正常流程代码沿着屏幕向下移动
提升代码可维护性和可读性
故障问题大多出现在复杂的条件语句和循环语句中
错误和异常处理
error尽可能提供简明的上下文信息链,方便定位问题
panic用于真正异常的情况
recover生效范围,在当前goroutine的被defer的函数中生效
性能优化建议
性能调优
简介
-
使用 Benchmark 进行基准测试;
-
尽可能为 slice 和 map 预分配内存(通过在
make时指定容量信息); -
注意为切片创建切片不会创建新的底层数组,这可能会导致内存泄漏发生,此时可用
copy代替 re-slice; -
多个字符串拼接时,使用
strings.Builder比直接使用+或使用bytes.Buffer更快(这和 Java 倒是十分相似,Java 也推荐使用StringBuilder拼接多个字符串;其实他们的底层逻辑都是类似的); -
当需要占位符时,可使用空结构体(
struct{})代替,其不会占据镇和内存空间; -
使用
atomic包代替锁修改变量