高质量编程
这是我参与「第三届青训营 -后端场」笔记创作活动的的第3篇笔记
1.1简介
正确性:是否考虑各种边界条件,错误的调用是否能够处理 可靠性:异常情况或者错误的处理策略是否明确,依赖的服务出现异常是否能够处理 简洁:逻辑是否简单,后续调整功能或新增功能是否能够快速支持 清晰:其他人在阅读理解代码的时候是否能清楚明白,重构或者修改功能是否不会担心出现无法预料的问题
1.2编码规范
-
注释应该做的
-
解释代码作用
-
注释公共符号
-
-
解释代码如何做的
-
解释代码实现的原因
-
解释代码为什么会出错
-
-
编码规范-命名规范
-
function
-
函数名不懈怠包名的上下文信息,因为包名和函数名总是成对出现的
-
当名为foo的包某个函数返回类型Foo时,可以省略类型信息而不导致歧义
-
当foo的包某个函数返回类型T时(T并不是Foo),可以在函数名中加入类型信息
-
package
-
只由小写字母组成,不包含大写字母和下划线等字符
-
简短并且包含一定的上下文信息,例如schema、task等
-
不要与标准库同名。例如不要使用sync或者strings
-
控制流程
-
优先处理错误情况,尽早返回或者继续循环来减少嵌套
-
-
编码规范-错误和异常处理
- 简单错误
-
指仅出现一次的错误,在其他地方不需要捕获该错误
-
优先使用errors.new来创建匿名变量来直接表示简单错误
-
如果有格式化的需求,使用fmt.Errorf
-
错误的Wrap和Unwrap
-
错误的wrap实际上是提供了一个error嵌套另一个error的能力,从而生成一个error的跟踪链
-
在fmt.Errorf中使用:%w关键字来讲一个错误关联至错误链中
2.错误判定 判定一个错误是否为特定错误,使用errors.Is。 不同于使用==该方法可以判定错误链上所有错误是否含有特定的错误
错误链上获取特定种类的错误,使用errors.As
recover
-
recover只能在被defer的函数中使用
-
嵌套无法生效
-
只在当前goroutine生效
-
defer的语句是后进先出
-
如果需要更多的上下文信息,可以recover后在log中记录当前的调用栈
1.3性能优化建议
Benchmark 如何使用
benchmark 基准测试 | Go 技术论坛 (learnku.com)
(6条消息) Go之Benchmark李子园的梦想的博客-CSDN博客benchmark go
func Fib(n int) int {
if n < 2 {
return n
}
return Fib(n-1) + Fib(n-2)
}
func BenchmarkFib10(b *testing.B) {
for n := 0; n < b.N; n++ {
Fib(10)
}
}
go test -bench=".."