这是我参与「第五届青训营 」伴学笔记创作活动的第 3 天
高质量编程简介及编码规范
高质量编程简介
简介
高质量
编写的代码能够达到正确可靠、简洁清晰的目标可以称之为高质量代码
- 边界条件? 完备?
- 异常处理? 稳定性?
- 易读?易维护?
编程原则
简单性
- 消除 “多余的复杂性”,以简单清晰的逻辑编写代码
可读性
- 代码是写给人看的,而不是机器
- 编写可维护代码的第一步是确保代码可读
生产力
- 团队整体工作效率!!!
编码规范
代码格式
-
gofmt
- Go官方自动化Go语言代码为官方统一风格
-
goimports
- 官方工具 + 依赖包管理
注释
注释要做的事情
-
解释代码的作用
-
解释代码如何实现
-
解释代码实现的原因
-
适当解释外部因素
-
提供额外的上下文
-
-
解释代码什么时候会出错
- 解释限制条件
什么时候进行注释
- 声明的每个公共符号:常量、变量、函数以及结构体
- 任何既不简短也不明显的公共功能
- 库中的任何函数
注意
代码是最好的注释
注释应该提供代码未表达的上下文信息
命名规范
变量
-
简洁胜于冗长
-
缩略词全部大写,但当其位于变量开头且不需要导出时,使用全小写
- 例如使用 ServeHTTP 而不是 ServeHttp
- 使用 XMLHTTPRequest 或者 xmlHTTPRequest
-
变量距离其使用的地方越远,则需要携带的上下文信息越多
- 全局变量在名字中需要更多的上下文信息
函数
-
函数名不携带包名的上下文信息,因为包名和函数名总是成对出现的
- 例如:
package http func Serve(I net.Listener, handler Handler) error func ServeHTTP(I net.Listener, handler Handler) error -
函数名尽量简短
包
- 只有小写字母构成,不包含大写字母和下划线
- 简短并包括一定的上下文信息
- 不要与标准库同名
控制流程
-
避免嵌套,保持正常流程清晰
-
尽量保持正常代码路径为最小缩进:优先处理错误或特殊情况,尽早返回或继续循环以减少嵌套
- 示例:
//Bad func OneFunc() error { err := doSomething() if err = nil { err := doAnotherThing() if err == nil { return nil } return err } return err }//Good func OneFunc() error { if err := doSomething(); err != nil { return err } if err := doAnotherThing(); err != nil { return err } return err }
错误和异常处理
简单错误
- 仅出现一次,且在其他地方不需要捕获该错误
- 优先使用
errors.New创建匿名变量直接表示简单错误
错误的 Wrap & Unwrap
- 实现了一个错误嵌套另一个错误的功能
- 以便于追踪错误
错误判定
error.Is判断错误链上是否包含特定错误error.As获取特定种类的错误
panic
- 不建议在业务代码中使用 panic
- 调用函数不包含 recover 会导致程序崩溃
- 如果问题能够被屏蔽或解决,使用error
- 当程序在启动阶段发生不可逆转的错误时,可以在 init 或 main 函数中使用 panic
revover
- 只能在 defer 的函数中使用
- 无法嵌套
- 只在当前 goroutine 生效
- 多个 defer 语句遵循栈的后进先出原则
小结
我的理解
- 注释和命名简洁但不简陋,要能让其他看代码的人所见即所得
- 一个团队使用同一种代码格式化工具