Go语言基础之高质量编程

113 阅读5分钟

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

Go语言高质量编程

一、高质量编程的原则

image-20230121114908721

二、编码规范-代码格式

gofmt

gofmt是GO官方开发团队提供的一个工具,可以帮助开发者来格式化他们代码并统一风格。其实gofmt是一个程序,可以读取标准输入,看传入的是文件路径或者目录,并格式化该文件或该目录下的所有.go文件

image-20230121111411326

gofmt的相关命令参数:

usage:gofmt[flags][path…]
 
-cpuprofile string
 
    将CPU配置文件写入此文件
 
-d 显示差异而不是重写文件
 
-e 报告所有错误(如果不使用此标记,则只会打印每行的第1个错误且只打印前10个错误。)
 
-l 列出格式与gofmt不同的文件
 
-R 字符串
 
    重写规则(例如“a[b:len(a)]->a[b:'')
 
-S 简化代码
 
-w 将结果写入(源)文件而不是stdout

-s简化代码

  • 去除数组、切片、Map初始化时不必要的类型声明

    如下形式的切片表达式:
        []T{T{}, T{}}
    将被简化为:
        []T{{}, {}}
    
  • 去除数组切片操作时不必要的索引指定

    如下形式的切片表达式:
        s[a:len(s)]
    将被简化为:
        s[a:]
  • 去除迭代时非必要的变量赋值

    如下形式的迭代:
        for x, _ = range v {...}
    将被简化为:
        for x = range v {...}
    如下形式的迭代:
        for _ = range v {...}
    将被简化为:
        for range v {...}
    ​
    

go imports

goimports 也是GO官方开发团队提供的工具,可以对项目的依赖的包进行管理,会自动增删依赖的包引用、将依赖包按字母排序并分类。

image-20230121111122433

小总结

使用规范的代码格式及统一的代码风格,可以极大的提升团队的开发效率,减少了因个人的差异化带来的不必要的麻烦

三、编码规范-注释

注释为代码的可读性提供了有效的保障

image-20230121115101824

注释还应为代码提供适合解释代码的外部因素,在相应的场景下提供额外的上下文,以供其他程序猿理解

image-20230121135030795

关于公共符号的注释

  • 包中声明的每个公共符号:变量、常量、函数体以及结构体都需要添加注释
  • 任何既不明显也不简短的公共功能必须予以注释
  • 无论长度、复杂度如何,都必须对库中的函数加以注释

image-20230121135557881

四、编码规范-命名

1.代码的命名

好的代码离不开好的命名

image-20230121120041430

看如下的代码:

image-20230121121117633

i和index仅在for循环里使用,且仅仅代表迭代的次数,index的额外冗长不不能提高代码的可读性

再看如下的代码:

image-20230121120001494

很显然,deadline有明确的指示,而T可代表所有和time相关的,因此使用有特殊含义的命名对代码的可读性事关重要

2.包的命名

image-20230121135826873

小总结

代码的命名的核心要素是降低读者理解代码的成本,要重点考虑上下文信息,一个好的命名必定是简洁清晰明了的。

五、编码规范-流程控制

1.避免嵌套

从最简单的if else 开始,如果两个分支都包含return语句,则可以去除冗余的else方便后续维护,else一般是正常的流程,如果在流程中还有新的判断逻辑,应该新增if判断,避免分支嵌套

image-20230121140815698

2.尽量保持代码路径为最小缩进

  • 优先处理特殊、错误情况,尽早返回或继续循环来避免嵌套

image-20230121141133506

函数最后一行返回错误,必须追溯到最早匹配的左括号,才能了解何时会触发错误,如果中间的代码很长,这必然会增加阅读的成本和理解的成本。如果后续流程新增了新的判断逻辑或新的函数调用,则又是一层嵌套,代码可读性的降低是指数级变化的。

image-20230121141611389

相比之前的代码,满足了优先处理错误情况的原则,可读性有了极大的提高。

小总结

  • 线性原理,处理逻辑尽量走直线,避免复杂的嵌套分支
  • 正常的流程应沿着屏幕向下移动(避免反复横跳[狗头])
  • 提升代码的可读性和可维护性
  • 故障问题一般出现在复杂的条件或循环语句中

六、编码规范-错误处理

1.简单错误

image-20230121142549127

2.错误链处理

image-20230121142715731

3.错误判定

image-20230121142821585

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

image-20230121142915968

4.panic

  • 不建议在业务代码中使用panic(如果所有goroutine中所有defer中没有recover会造成程序崩溃)
  • 如果问题可以被屏蔽或解决,建议用errors代替panic
  • 当程序在启动阶段发生不可逆转的错误时,应在inti或main中使用panic

image-20230121143518054

5.recover

  • recover只在被defer的函数中使用
  • 嵌套无效
  • 只在当前goroutine生效
  • defer后进先出
  • 需要更多的上下文信息,可在recover后,在log中记录当前的栈

image-20230121143820042

总结

高质量的代码依赖于高质量的命名、流程控制、注释、错误处理,写代码并不是跑起来就完事那么简单,要注重代码的可读性和可维护性(低耦合,高内聚),养成一个好的编码习惯是成为一名优秀程序猿的重中之重。