高质量编程简介及编码规范(三)|青训营笔记

61 阅读3分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 14 天

一、本堂课重点内容:

  • 高质量编程
  • 小测

二、详细知识点介绍:

  • 高质量编程

1.2.4 编码规范——控制流程

避免嵌套,保持正常流程清晰

例子:

image.png

如果两个分支中都包含return语句,则可以去除冗余的else。

尽量保持正常代码路径为最小缩进

  • 优先处理错误情况/特殊情况,尽早返回或继续循环来减少嵌套。

例子:

image.png

在该例子中:

  • 最常见的正常流程的路径被嵌套在两个if条件内
  • 成功的退出条件是return nil,必须仔细匹配大括号来发现
  • 函数最后一行返回一个错误,需要追溯到匹配的左括号,才能了解何时会触发错误
  • 如果后续正常流程需要增加一步操作,调用新的函数,则又会增加一层嵌套

调整后:

image.png

GO仓库中的例子:

image.png

在该例中,对于异常情况会提前返回,在异常情况处理完成后进入正常的处理流程。

小结

  • 线性原理,处理逻辑尽量走直线,避免复杂的嵌套分支
  • 正常流程代码沿着屏幕向下移动
  • 提升代码可维护性和可读性
  • 故障问题大多出现在复杂的条件语句和循环语句中

1.2.5 编码规范——错误和异常处理

简单错误

  • 简单的错误指的是仅出现一次的错误,且在其他地方不需要捕获该错误
  • 优先使用errors.New来创建匿名变量来直接表示简单错误
  • 如果有格式化的需求,使用fmt.Errorf

例子:

image.png

错误的Wrap和UnWrap

  • 错误的Wrap实际上是提供了一个error嵌套另一个error的能力,从而生成一个error的跟踪链
  • 在fmt.Errorf中使用%w关键字来将一个错误关联至错误链中

Go1.13在errors中新增了三个新API和一个新的format关键字,分别是errors.Iserrors.Aserrors.Unwrap以及fmt.Errorf%w。如果项目运行在小于Go1.13的版本中,导入golang.org/x/xerrors来使用

例子: image.png

github.com/golang/go/b…

错误判定

  • 判定一个错误是否为特定错误,使用errors.Is
  • 不同于使用==,使用该方法可以判定错误链上的所有错误中是否含有特定的错误

例子:

image.png

github.com/golang/go/b…

  • 在错误链上获取特定种类的错误,使用errors.As

例子:

image.png

github.com/golang/go/b…

panic

  • 不建议在业务代码中使用panic
  • 调用函数不包含recover会造成程序崩溃
  • 若问题可以被屏蔽或解决,建议使用error代替panic
  • 当程序启动阶段产生不可逆转的错误时,可以在init或main函数中使用panic

例子: image.png

recover

  • recover只能在被defer的函数中使用
  • 嵌套无法生效
  • 只在当前goroutine生效
  • defer 的语句是后进先出

例子:

image.png

  • 如果需要更多的上下文信息,可以recover后在log中记录当前的调用栈

例子:

image.png

github.com/golang/webs…

小结

  • error尽可能提供简明的上下文信息链,方便定位问题

  • panic用于真正异常的情况

  • recover生效范围:在当前goroutine的被defer的函数中生效

  • 小测

哪种命名方式更好?

①:

image.png

第一种更好,详见下图实际调用时的结果:

image.png

②:

image.png

第二种更好,因为第一种省去了应有的信息。

image.png

程序的输出是什么?

image.png

  • defer语句会在函数返回前调用
  • 多个defer语句是后进先出

最终输出:31

三、引用参考: