高质量编程和代码规范

114 阅读6分钟

高质量编程

简介

什么是高质量编程

编写的代码能够达到正确可靠,简洁清晰的目标

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

编程原则

  • 简单性
    • 消除多余的复杂性,以简单清晰的逻辑编写代码
    • 不理解的代码无法修复改进
  • 可读性
    • 代码是写给人看的,而不是机器
    • 编写可维护代码的第一步是确保代码可读
  • 生产力
    • 团队整体工作效率

编码规范

代码格式

推荐使用gofmt自动格式化代码,能格式化为官方统一风格

goimports:也是Go语言官方提供的工具,实际上等于gofmt加上依赖包管理,自动增删依赖包的引用,按字母排序分类

注释

  • 注释应该解释代码作用(公共符号)
  • 注释应该解释代码是如何做的(实现过程)
  • 注释应该解释代码实现的原因(外部原因,额外上下文)
  • 注释应该解释代码什么情况会出错(限制条件)

公共符号始终要注释

  • 包中声明的每一个公共符号,变量,常量,函数都要添加注释
  • 任何不明显也不简短的公共功能要添加注释
  • 库中任何函数都要添加注释
  • 实现接口的方法不需要注释

命名规范

核心目标时降低阅读理解代码的成本,重点考虑上下文信息,设计简洁清晰的名称

变量

  • 简洁胜于冗长
  • 缩略词全大写,但位于变量开头且不需要导出时,使用全小写
    • 例如使用serveHTTP而不是ServeHttp
    • 使用XMLHTTPRequest或xmlHTTPRequest
  • 变量距离越远就需要越多的上下文信息

函数

  • 不需要携带包名的上下文信息,因为这两者总是成对出现
  • 函数名尽量简短

  • 只由小写字母组成,不包含大写字母和下划线
  • 包含一定上下文信息
  • 不要与标准库同名
  • 不使用常用变量名做包名
  • 使用单数而非复数
  • 谨慎使用缩写

控制流程

  • 避免嵌套,保证流程清晰

image.png

  • 尽量保证最小缩进

image.png

image.png

错误和异常处理

  • 简单错误

    • 仅出现一次的错误,且其他地方不需要捕获该错误
    • 优先使用error.New 来创建匿名变量名来直接表达简单错误
    • 如果需要格式化,使用fmt.Errorf
  • 错误的Wrap和Unwrap

    • 错误的Wrap提供了一个error嵌套力另一个error的能力,生成了一个error的跟踪链
    • 在fmt.Error中使用:%w关键字来将一个错误关联至错误链中
  • 错误判定

    • 判定一个错误是否为特定错误使用errors.Is
    • 使用上述方法可以判断错误链上所有错误是否含有特定错误
    • 获取特定种类的错误,使用errors.As
  • panic

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

image.png

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

总结

  • error 尽可能提供简明的上下文信息链,方便定位问题
  • panic用于真正的异常情况
  • recover生效范围在当前goroutine的被defer的函数中生效

性能优化建议

  • 性能优化的前提是满足正确可靠,简洁清晰等质量因素
  • 是综合评估,有时候时间效率和空间效率可能对立
  • 针对GO语言特性,介绍go相关的性能优化建议

benchmark

基准性能测试的工具

image.png

slice

  • 预分配内存,使用make()时提供容量信息
  • 在已有切片上创建切片不会创建新的底层数组,原底层数组在内存中有引用,得不到释放。解决方法:用copy代替reslice

map

  • 预分配内存,提前预估需要的空间 -提前分配空间奸商内存拷贝和Rehash的消耗

使用strings.Bulider

  • +性能最差,strings.Bulider,bytes.Buffer相近,strings.Buffer更快
  • bytes.Buffer转化为字符串时重新申请的空间
  • strings.Builder直接将底层的[]byte转化成字符串类型返回

空结构体

  • 空结构体实际上不占用任何内存空间
  • 可以做占位符使用

atomic

  • 锁的实现是通过操作系统实现的,属于系统调用
  • atomic操作是通过硬件实现的,效率比锁高
  • sync.Mutex应该用来保护一段逻辑而不是一个变量
  • 对于非数值操作,可以用atomic.Value,能承载一个interface{}

image.png

image.png

总结

高质量编程和代码规范是软件开发中非常重要的两个方面。它们不仅能够提高代码的可读性和可维护性,还能够提高开发效率和减少错误。

遵循一定的编程规范和代码风格可以大大提高编程能力。例如,避免使用过长的函数和过于复杂的逻辑结构,而是将代码分解为多个简单的函数,每个函数都有一个明确的目的。这样,在修改或调试代码时,就可以更快地定位问题所在。

此外,遵循一些基本的代码风格规范,例如缩进、命名约定和注释规范,也能够让代码更加清晰易读。当其他人需要阅读或修改代码时,他们也能够更快地理解思路。

当然,关于高质量编程和代码规范,还有很多值得探讨的话题。例如,不同的编程语言和开发环境往往有着不同的编程规范和代码风格。程序员需要不断学习新的技能,并根据实际情况选择合适的规范和风格。

此外,随着软件开发行业的不断发展,编程规范和代码风格也在不断演变。程序员需要紧跟行业发展的步伐,不断更新知识储备,以便能够更好地适应新的技术环境。

在实际开发过程中,还需要注意代码的可测试性和可扩展性。良好的代码结构和清晰的逻辑关系能够让程序员更容易地编写测试用例,并在未来更好地扩展功能。

总之,高质量编程和代码规范对于软件开发至关重要。它们不仅能够提高开发效率,还能够提高代码的可维护性和可读性。作为一名程序员,应该时刻牢记这些原则,并在日常开发中不断实践和提高。这样,才能够写出更加优秀的代码,并为整个行业做出贡献。