Go语言高质量编程|青训营笔记

168 阅读4分钟

高质量编程

高质量编程简介

什么是高质量

编写代码的时候能够达到正确可靠、简洁清晰的目标可以称之为高质量代码

  • 各种边界条件是否考虑完备
  • 异常情况处理,稳定性保证
  • 易读易维护

编写简单,可读,可维护的Go代码的十个建议——go语言开发者Dave Cheney

Package的单一职责原则

对于一个Go package来说,好的设计是只表达一个主题,提供的是一系列与该主题相关的方法,并且具有规范的命名。试着把你package的名字想象成一个产品营销的演讲,尽量用一个最恰当的词来描述它所提供的内容。

错误的及时处理

健壮的代码总是能在程序崩溃之前及时地处理错误。尽管 if err!= nil { return err }冗长地出现在代码当中,但是它是非常有用的,总能在出错的地方及时给你一个反馈,所以不要抵触这种错误处理。不过对于panicrecover的使用来说,就要谨慎和克制一些。

及时返回避免嵌套

你每多一个条件嵌套,都会或多或少地对程序的性能造成影响,也会造成可读性的降低。所以尽量避免多层嵌套的控制流程。

是否使用并发由调用方决定

如果你的库使用了并发,让调用者选择是否要并发运行你的库或函数,不要强加于他们。

了解你的goroutine的生命周期

Goroutines占用的资源包括锁,变量,内存等。只有及时停止goroutine才能释放这些资源,所以你务必 了解你的goroutine的生命周期。

Avoid package level state

Seek to be explicit, reduce coupling, and spooky action at a distance by providing the dependencies a type needs as fields on that type rather than using package variables.(实在不知道怎么解释,就不误人子弟了)

简洁至上

简洁并不是复杂的反义词,而是意味着可读性和可维护性。在可能的情况下,选择更简洁的解决方案

测试用例是你package API的门面

尽管用户使用的是你的API,但是详尽的测试用例能够给用户足够的安全感。

Talk is cheap, show me your benchmark

有太多的代码打着提升性能的旗号而没有考虑其可维护性。要警惕过度优化带来的紧耦合、封装性差、可读性差的问题。如果你选择承担这些成本,一定要给出有说服力的理由。

克制是一种美德

适当地使用goroutines、channels、locks、interface、embedded等技术,切勿炫技。

可维护性

可维护性包括清晰,易读,简单等方面。你能想象到在你走后,你同事会如何看待你你留下的一坨代码吗?所以你现在就应该考虑一下如何让后面的人更容易地接手你的代码。

编码规范

代码格式

推荐使用gofm自动格式化代码

注释

注释应该做的

  • 注释应该解释代码作用(公共符号始终要注释)

截屏2023-06-11 14.06.34.png

  • 注释应该解释代码如何做的

截屏2023-06-11 14.06.56.png

  • 注释应该解释代码实现的原因

截屏2023-06-11 14.08.10.png

  • 注释应该解释代码什么情况会出错

截屏2023-06-11 14.09.50.png

命名规范

  • 变量命名

截屏2023-06-11 14.11.43.png

  • 函数命名

截屏2023-06-11 14.14.07.png

  • 包命名

截屏2023-06-11 14.15.39.png

控制流程

  • 尽量保持正常代码路径为最小缩进
  • 避免复杂的嵌套分支
  • 提升代码的可读性和可维护性
  • 正常代码沿着屏幕向下移动

异常处理

  • 简单错误

截屏2023-06-11 14.22.02.png

  • 错误的Wrap和Unwrap

截屏2023-06-11 14.23.05.png

  • 错误判定:在错误链上获取特定种类的错误,使用error.As
  • panic
    • 不建议在业务代码中使用panic
    • 调用函数不包含recover会导致程序崩溃
    • 若问题可以被屏蔽或者解决,建议使用error代替panic
    • 当程序在启动阶段发生不可逆转的错误时,可以在init或main函数中使用panic
  • recover
    • recover只能在defer的函数中使用
    • 嵌套无法生效
    • 只在当前goroutine生效
    • 如果需要更多的上下文信息,可以在recover后在log中记录当前的调用栈