这是我参与「第三届青训营 -后端场」笔记创作活动的的第2篇笔记。
Golang编程技巧
编程的原则
- 简单性:消除多余的复杂性,命名简单易懂
- 可读性:代码加注释可以帮助他人快速理解代码
- 生产力:统一代码风格,方便团队工作
1.编码规范之命名
- 命名尽量简单,不要出现信息冗余。
2.编码规范之控制流程
- 如果两个分支中都包含return语句,可以去除冗余的else。
if ok {
return x
}else{
return y
}
if ok {
return x
}
return y
第一种代码在go的早期版本可能会报错,但现在已经修复了该bug。
- 优先处理错误情况,减少代码嵌套,提高可读性。
err := doSomething()
if err == nil{
err := doAnother(){
...
}
}
if err := doSomething(); err != nil{return err}
if err := doAnother(); err != nil{return err }
2.编码规范之错误和异常处理
- 一般情况出现简单的错误可以直接使用errors包中的New()函数来生成一个包含错误信息的error,并返回。
- 对于复杂的错误,可以在fmt.Errorf中使用 %w关键字来嵌套错误。这样不会丢失原来的错误信息。
- 在Go语言中,如果出现了panic则表示程序无法继续运行下去,一般需要谨慎使用。使用recover函数可以让程序即使发生了panic也可以正常退出。但是需要注意:(1)recover只能在defer函数中使用(2)只在当前goroutine生效(3)嵌套无法生效
3.性能优化之预分配内存
在Go语言中Slice是一个经常使用的数据结构,因此了解一些关于slice性能优化的技巧是必要的。
- 使用Slice时,尽量使用make()初始化时提供容量信息,让内存一次性分配好,这样就可以避免以后添加元素后容量不够,需要重新扩容的问题。同样的,使用Map也应该尽可能地预分配内存。
- 在已有切片的基础上创建切片,不会创建新的底层数组, 这会使得原来的底层数组在内存中有引用,无法释放。建议用copy 代替 reslice
4.字符串拼接
Go语言中的字符串拼接大概有四种方法。
- 使用"+"操作符来拼接字符串
- 使用fmt.Sprintf()
- 使用strings.Join()
- 使用bytes.Buffer
- 使用strings.Builder
前三种操作的性能差别不大,后两种的性能也差别不大,可能经过优化后的strings.Builder更好一点,但是后两种操作在拼接大量字符串时性能远高于另外三种方法。
5.空结构体
空结构体 struct{}实例不占据任何的内存空间,可作为占位符使用,它可以节省资源。一个使用场景就是集合的实现,在Go语言中是没有集合这个数据结构的。我们可以用Map来实现类似的功能,因为Map的key是唯一的,这时我们其实是不需要Map的值的,因此可以用空结构体来占用。
此外也可以用Bit数组来实现集合。
6.atomic包
atomic操作是通过硬件实现的,效率比sync.Mutex的效率高。
锁的实现是通过操作系统来实现的,属于系统调用。
sync.Mutex应该用来保护一段逻辑,而不仅仅是一个变量。