这是我参与「第五届青训营 」伴学笔记创作活动的第 4 天
高质量编程
标准
正确可靠、简洁清新
原则
简单性、可读性、生产力
规范
代码格式
gofmt自动格式化代码、goimports自动化导包以及格式化代码
注释
代码是最好的注释、注释应该提供代码未表达出的上下文信息
解释代码作用、解释代码如何做、解释代码实现的原因(代码的外部因素、额外上下文)、解释代码何时出错(限制条件)
包中声明的变量、常量、函数、结构体;库函数;不明显且不简短的功能都需要加注释
不需要注释实现接口的方法
命名规范
核心目标是降低阅读理解代码的成本、重点考虑上下文信息,设计简洁清晰的名称
变量命名:简洁、缩略词全大写,当缩略词位于变量开头且不需要导出时全小写、变量距离被使用的地方越远则越需要提供更多的上下文信息
函数命名:不携带包名的上下文信息、尽量简短
包名:只由小写字母组成、简短且包含上下文信息、不与标准库重名
控制流程
避免嵌套、保持流程清晰、尽量保持正常代码路径为最小缩进(优先处理错误或特殊情况、尽早返回或继续循环来减少嵌套)
错误与异常处理
error尽可能提供简明的上下文信息链,方便定位问题
panic用于真正异常情况
recover在协程被defer德函数中生效
简单错误(错误只出现一次,其他地方不需要捕获该错误)优先使用errors.New创建匿名变量来直接表示简单错误
错误的Wrap:提供了一个error嵌套另一个error的能力,生成error跟踪链,在fmt.Errorf中使用%w关键字将错误关联至错误链中
判断错误的指定类型使用errors.Is、获取指定错误的路径使用errors.As
panic(严重错误):不建议在业务代码中使用panic、调用函数不包含recover会造成程序崩溃、问题可以被解决的话建议使用error代替panic
程序启动阶段发生不可逆转的错误建议使用panic今早暴露错误
recover:只能在被defer的函数中使用、嵌套无法生效、只在当前协程生效、defer的语句是后进先出
defer语句会在函数返回前前调用、多个defer语句是后进先出
性能调优实践
Benchmark工具用于基准性能测试
提高时间性能
在使用切片(slice)时尽可能在使用make()初始化切片时提供容量信息(同map)
字符串拼接使用strings.Builder(底层是[]byte数组,采用内存扩容策略)代替+(重新分配内存)
提高空间性能
使用空结构体节省内存(使用map空结构体代替set)
多线程编程:使用atomic包性能比加锁更好