这是我参与「第五届青训营 」伴学笔记创作活动的第 5 天。
今天主要整理一下青训营课程「高质量编程」中学到的知识点。
高质量编程
什么是高质量编程?
- 正确可靠
- 边界条件
- 异常处理
- 简洁清晰
如何写好代码中的注释?
首先,代码是最好的注释,注释应当提供代码未表达出的上下文信息。
注释应该解释清楚的:
- 代码作用
- 代码如何实现的
- 代码实现的原因
- 代码什么时候会出错
公共符号需要注释
例外:实现接口的方法不需要注释
命名规范
- 变量命名
- 简洁胜于冗长
- 缩略词全大写 例如ServeHTTP
- 全局变量需要更多的上下文信息,以便快速知道它的含义
- 函数名
- 函数名不用携带包名的上下文信息
- 例如http包中,创建服务的函数写为Serve而不是ServeHTTP
- 包名
- 只由小写字母组成,不包含大写字母和下划线等字符
- 不与标准库同名
- 不使用常用变量名作为包名 例如bufio而不是buf
- 使用单数而不是复数 例如encoding而不是encodings
错误处理
- 简单错误
- 简单的错误指的是仅出现一次的错误,且在其他地方不需要捕获该错误
- 优先使用errors.New来创建匿名变量来表示简单错误
- 如果有格式化的需求,使用fmt.Errorf
- 复杂错误
Wrap提供了一个error嵌套另一个error的能力,从而生成一个error的跟踪链 在fmt.Errorf中使用%w关键字将一个错误关联到错误链中
- errors.Is 判断一个错误是否为指定错误
- errors.As 获取特定种类的错误
- errors.Unwrap 获取原始错误
使用%v是将一个error转换成另一个error,不能使用Unwrap获取原始的error,而使用%w是嵌套一个error,可以获取原始的错误信息。
panic
不建议在业务代码中使用panic
当程序启动阶段发生不可逆转的错误时,可以在init或main函数中使用panicrecover
recover只能在被defer的函数中使用,在其他地方调用recover返回nil。recover应当直接位于defer函数体里面,不能出现在另外一个嵌套函数中。recover处理异常后,直接退出,不会执行panic之后的逻辑。- 由于
panic只能触发当前goroutine的defer调用,所以只要defer调用中有recover,就能处理当前goroutine触发的panic,但是其他goroutine中的defer调用对其不起作用,也就是只在当前goroutine生效。 - defer语句是后进先出
- 可以调用debug.Stack()获取当前的调用栈获取更详细的信息