这是我参与「第五届青训营 」伴学笔记创作活动的第3天,感觉比昨天容易理解,但与之相对的,非常需要实践去支撑,遗憾的是时间有点不够,争取快速过一遍数据库和网络,有对应基础好好完成项目。
1.高质量编程
1.1 简介
易读易维护
各种边界环境考虑完备
异常情况处理,稳定性保证
通用原则 简单性
可读性
生产力
1.2 编码规范
1.2.1 代码格式
gofmt自动格式化代码为官方同一风格
goimports
等于gofmt加上依赖包管理
自动增删pkg的引用,并按字母排序
1.2.2 注释
包中每个公共的符号
库中任何函数都要注释
解释代码作用,
如何做的,
实现原因,给出额外上下文
什么情况会出错,解释代码的限制条件
1.2.3 命名规范
variable
-
缩略词全大写,在变量开头不需要导出时全小写
-
变量对使用地方越远,携带越多上下文信息
function
- 函数名不携带包名的上下文信息,因为两者总是成对存在
pkg
- 只有小写字母构成
- 包含一定上下文
- 与标准库不同名
以下规则尽量满足
- 不要用常用变量名做包名
- 使用单数
- 谨慎地使用缩写
1.2.4 控制流程
避免嵌套 保持正常代码路径为最小缩进
1.2.5 错误和异常处理
简单错误
- 仅出现一次的错误,其他地方不需要捕获该错误
- 优先使用 errors.New来创建匿名变量来直接表示匿名错误
- 有格式化要求,使用fmt.Errorf
错误的Wrap和Unwrap
- 错误的Wrap提供一个error嵌套另一个error的能力,生成error的跟踪链
- 在fmt.Errorf中使用%w关键字将一个错误关联至错误链中
错误判定
- 判断一个错误是否是特定错误,使用errors.ls
- 不同于使用 ==,使用该方法可以判定错误链上的所有错误是否含有特定的错误
错误判定
在错误链获取特定种类的错误,使用errors.As
panic
- 真正异常的情况
- 不建议在业务中使用panic
- 发生不可逆错误时在init和mian函数使用panic
recover
- recover 只能在被defer的函数中使用
- 嵌套无法生效
- 只在当前goroutine生效
- defer的语句是后进先出
1.3 性能优化建议
1.3.1 benchmark
1.3.2 Slice
slice预分配内存
- 尽可能在使用make初始化切片时提高容量大小
- 本质是避免数组复制
大内存释放
- 在已有切片上创建新切片
- 原底层数组在内存中有引用,得不到释放
- 可使用copy代替re-slice
map预分配内存
- 不断向map添加元素会触发扩容
- 提前分配好空间可以减少内存拷贝消耗
1.3.4 字符串处理
使用strings.Builder
- s+=str涉及内存分配 string.builder底层是[]byte数组,再变回string
1.3.5 空结构体
实例不占用任何内存空间 占位符
1.3.6 atomic包
多线程