Go 高质量编程

 Go 󰈭 1572字

编码规范

代码格式

一定使用gofmt进行格式化。

注释

  • 解释代码的作用 这种注释适合说明公共符号,比如注释解释向外提供的函数等,只有在函数功能简单而明显时才应该省略这些注释。
  • 解释代码的实现 对代码中复杂、隐晦的逻辑进行说明。不要使用自然语言直接翻译代码,这不好。
  • 解释代码实现的原因 注释可以解释代码的外部因素,这些因素脱离了上下文后通常难以理解。
  • 解释代码可能出错的情况 注释应该提醒使用者一些潜在的限制条件或者无法处理的情况。
  • 公共符号的注释 Google Style指南有两条规则:任何既不明显也不简短的公共功能必须予以注释;无论长度或者复杂度如何,库中的任何函数都必须予以注释。一个例外是,不要注释实现接口的方法!

命名规范

变量

  • 简洁胜于冗长
  • 缩略词使用全大写(如HTTP,XML等),但当其位于变量开头且不需要导出时,使用全小写(如使用ServeHTTP而不是ServeHttp, 使用XMLHTTPRequest或者xmlHTTPRequest)
  • 全局变量在名字中需要携带更多的上下文信息,使得不同地方都可以轻易辨认出其含义。

函数

  • 函数名不包含包名的上下文信息,因为包和函数总是成对出现的。
  • 尽量简短
  • 当名为foo的包中某个函数的返回类型是Foo时,可以省略类型信息而不产生歧义,当返回的是其余类型时,则可以在函数名中加入类型信息。

  • 只有小写字母组成。
  • 简短并包含一定的上下文信息
  • 不和标准库同名。
  • 尽量满足以下规则:
    • 不使用常用变量名作为包名
    • 使用单数而不是复数
    • 谨慎地使用缩写,利用使用fmt在不破坏上下文的情况下比format更加简短。

控制流程

  • 遵循线性原理,尽量避免嵌套,保持正常流程清晰。
  • 尽量保持正常代码路径为最小缩进,优先处理特殊、错误情况,尽早开始重新循环来减少嵌套。

错误和异常处理

简单错误

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

对错误的Wrap和Unwrap

通过在fmt.Errorf中使用%w关键字可以将一个错误关联到一个错误链中,从而追踪错误发生的上下文环境。

错误判定

  • 判定一个错误是否为特定错误,使用errors.Is;不同于==,该方法将判定错误链上是否含有特定的错误。
  • errors.As区别于Is的地方在于其将提取出制定类型的错误并将其赋值给定义好的变量。

Panic

若问题可以被屏蔽或解决,建议使用error代替panic;但当程序在启动阶段发生不可逆转的错误时,可以在init或main中使用panic崩溃程序。

性能优化

Benchmark

使用Go语言提供的基准性能测试工具benchmark

Slice

尽可能在使用make初始化切片时提供容量信息,减少内存分配次数。

关于Slice有可能会出现大内存未释放的情况。由于在已有的切片上创建新的切片,底层使用指针对数组进行引用,因而当在一个大切片上创建一个小切片时,大切片数组占据的内存不会被释放。一种解决办法是使用copy代替重切片。

Map

类似Slice,尽可能地在make时为Map提供容量信息,减少内存拷贝和重哈希的消耗。

字符串处理

go
1str += ...
2
3var builder strings.Builder
4builder.WriteString(str)
5
6buf := new(bytes.Buffer)
7buf.WriteString(str)

代码中展示了三种不同的字符串拼接操作,使用+的拼接性能最差,而Builder和Buffer相近,Buffer最快。由于字符串在go中是不可变类型,内存大小占用固定,因而使用+每次都会重新分配内存。而另外两个结构的底层都是[]byte数组,通过内存扩容策略不需要每次都要重新分配内存。

空结构体

空结构体struct{}不占用任何的内存空间,可以节省资源,或者仅仅作为占位符存在。

go
1s := make(map[int]struct{})
2
3s := make(map[int]bool)

代码中展示了两种set的书写方式,使用空结构体可以省去bool类型所占用的一个1个字节空间。。

atomic

锁的实现是通过OS来实现,属于系统调用,而atomic通过硬件实现,效率比锁高。

嗨! 这里是 rqdmap 的个人博客, 我正关注 GNU/Linux 桌面系统, Linux 内核 以及一切有趣的计算机技术! 希望我的内容能对你有所帮助~
如果你遇到了任何问题, 包括但不限于: 博客内容说明不清楚或错误; 样式版面混乱; 加密博客访问请求等问题, 请通过邮箱 rqdmap@gmail.com 联系我!
修改日志
  • 2023-09-01 18:14:49 单独划分ACM专题; 移动部分博客进入黑洞归档
  • 2023-05-29 23:05:14 博客结构与操作脚本重构
  • 2023-05-08 21:44:36 博客架构修改升级
  • 2022-11-16 01:27:34 迁移老博客文章内容