高质量编程 | 青训营

66 阅读2分钟

高质量编程

高质量代码:正确可靠,简洁清晰

代码格式:使用gofmt格式化代码,goimports在此基础上加入了依赖包管理功能

注释:解释代码作用、为何实现、具体实现过程、什么情况会出错(限制条件)。解释公共符号:变量、常量、函数、结构体、公共功能、所有库函数

命名规范:

  • 变量:缩略词全大写,但当其位于变量开头且不需要导出时,使用全小写,如ServerHTTP,xmlHTTPRequest;变量距离其被使用的地方越远,需要携带越多的上下文信息
  • 函数:驼峰命名法,首字母大写。如果属于一个包,就不用带这个包的名字。比如http.Serve()而不是http.ServeHTTP()
  • package:只有小写字母,不能与标准库、变量名同名,包含一定上下文信息,使用单数

控制流程:

  • 避免嵌套,优先处理特殊情况,尽早返回或者继续循环
  • 从上到下是正常流程代码

错误和异常处理

  • 简单错误:仅出现一次的,使用errors.New来创建匿名变量表示简单错误,或者使用fmt.Errorf格式化
  • error通过Wrap(%w)进行嵌套,生成跟踪链
  • 使用errors.Is()判断一个错误是否为特定的某个错误,整个错误链都会比较;errors.As()在错误链上获取特定错误
  • panic(string):触发异常,一般业务中不使用
  • recover:从panic的异常状态中恢复,在当前goroutine的被defer的函数中使用

性能优化

  • Benchmark工具:go test -bench=. -benchmem运行所有基准测试,并显示每个测试的内存分配信息
  • 生成slice时预分配内存:data := make([]int,0,size)
  • 在从一个切片中取某几个元素时,使用copy()替代直接取元素,因为直接取元素的话即使原来的切片不用也不会被释放,copy出来以后原来的切片就可以释放了
  • map预分配内存:data := make(map[int]int, size)
  • 字符串拼接:使用strings.Builder代替+=,因为+每次都需要重新分配内存,strings.Builder底层是[]byte数组
  • 空结构体:不占用空间,将map作为Set使用时可作为占位符,s[key]=struct{}{},因为只需要key
  • atomic包:原子操作,通过硬件实现,相比系统调用实现的锁操作,atomic效率更高