高质量编程| 青训营笔记

126 阅读3分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的的第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{}