这是我参与「第三届青训营 -后端场」笔记创作活动的的第1篇笔记
编码规范
代码格式
可以使用gofmt自动格式化代码
gofmt在goland IDE中可以进行配置
在settings中搜索file watcher
选择
go fmt
在
arguments参数栏添加-x参数后,apply即可
go fmt 为 gofmt的一层封装,go fmt = gofmt -l -w
注释
- 应该解释代码如何做的
- 解释代码实现的原因
- 解释代码什么情况会出错
- 公共符号始终要注释
代码是最好的注释
注释应该提供代码未表达出的上下文信息
命名规范
变量
- 简洁胜于冗长
- 缩略词全大写,位于变量开头,且不导出,全小写
- 变量距离使用地方越远,需要携带更多上下文信息
函数
- 函数名不需要携带包名的上下文信息
- 函数名尽量简短
- 名为foo的包某个函数返回类型Foo时,可省略类型信息而不导致歧义
- 名为foo的包某个函数返回类型T时,可以在函数名中加入类型信息
package
- 小写字母,不使用大写字母、下划线
- 包含一定上下文信息
- 不与标准库同名
- 不使用常用变量名作为包名
- 单数不是复数
- 谨慎使用缩写
控制流程
- 避免复杂的嵌套
- 优先处理错误或特殊情况,尽早返回或继续循环减少嵌套
错误和异常处理
- 简单错误 使用
errors.New创建匿名变量,使用fmt.Errorf格式化错误 - 复杂错误 fmt.Errorf
%w打印错误调用链 - panic 不建议业务代码中使用,调用函数不包含recover会直接崩溃,在初始化时出现不可逆错误可以使用panic直接结束
- recover只能在defer中使用
性能优化
切片及映射
s := make([]int, 0, 10)
m := make(map[string]int, 8)
切片及映射在初始化时建议初始化容量,可以避免频繁扩容对程序性能产生影响
字符串拼接
下面将使用benchmark test去分析字符串拼接时各个处理方式的性能
func BenchmarkStringAdd(b *testing.B) {
for i := 0; i < b.N; i++ {
//StringAdd(s1, s2)
MultiStringAdd(s1)
}
}
func BenchmarkStringBuilder(b *testing.B) {
for i := 0; i < b.N; i++ {
//ByStringBuilder(s1, s2)
MultiByStringBuilder(s1)
}
}
func BenchmarkBytesBuffer(b *testing.B) {
for i := 0; i < b.N; i++ {
//ByBytesBuffer(s1, s2)
MultiByBytesBuffer(s1)
}
}
func StringAdd(a, b string) string {
return a + b
}
func ByStringBuilder(a, b string) string {
sb := strings.Builder{}
sb.WriteString(a)
sb.WriteString(b)
return sb.String()
}
func ByBytesBuffer(a, b string) string {
buf := bytes.NewBuffer(nil)
buf.WriteString(a)
buf.WriteString(b)
return buf.String()
}
func MultiStringAdd(a string) string {
s := ""
for i := 0; i < 100; i++ {
s += a
}
return s
}
func MultiByStringBuilder(a string) string {
sb := strings.Builder{}
for i := 0; i < 100; i++ {
sb.WriteString(a)
}
return sb.String()
}
func MultiByBytesBuffer(a string) string {
buf := bytes.NewBuffer(nil)
for i := 0; i < 100; i++ {
buf.WriteString(a)
}
return buf.String()
}
当仅有两个字符串进行拼接时,string operation add的效率明显优于stringBuilder及BytesBuffer
当多次字符串拼接时,string operation add的效率下降明显,需要频繁申请内存分配,stringBuilder的底层为byte数组,每次扩容都会扩为原先的2倍,减小了扩容次数
总结: 在小数据量时,优先选用
+拼接,在大数据量时选用stringBuilder或BytesBuffer性能差别不大