day03高质量编程代码规范 | 青训营日记

66 阅读3分钟

编写更加清晰整洁的代码

高质量编程简介

高质量是一个相对主观的概念。主要有这几方面

  • 各种边界条件是否完备
  • 异常情况处理是否完备
  • 易读易维护

编程原则

  • 简单性:消除多余的复杂性,以简单清晰的逻辑编写代码。
  • 可读性:编写可维护代码的第一步是可读
  • 生产力:团队的整体效率

编程规范

编写高质量的Go代码

公共符号始终要注释

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

代码格式

使用gofmt自动格式化,GoLand可以自动格式化

注释

注释应该做的

  • 注释应该解释代码作用
  • 注释应该解释代码如何做的
  • 注释应该解释代码实现的原因
  • 注释应该解释代码什么情况会出错

变量命名规范

变量

简洁胜于冗长 缩略词全大写,但当其位于变量开头且不需要导出时,使用全小写

  • 例如使用 ServeHTTP 而不是 ServeHttp
  • 使用 XMLHTTPRequest 或者 xmIHTTPRequest 变量距离其被使用的地方越远,则需要携带越多的上下文信息
  • 全局变量在其名字中需要更多的上下文信息, 使得在不同地方可以轻易辩认出其含义

这个例子是函数参数的名称示例,为了简短将时间参数 deadline 改成了 t t 常代指任意时间 deadline 指截止时间,有特定的含义 函数提供给外部调用时,签名的信息很重要,要将自己的功能准确表现出来,自动提示一般也会提示函数的方法签名,通过参数名更好的理解功能很有必要,节省时间

image.png

function

  • 函数名不携带包名的上下文信息, 因为包名和函数名总是成对出现的
  • 函数名尽量简短
  • 当名为 foo 的包某个函数返回类型 Foo 时, 可以省略类型信息而不导致歧义
  • 当名为 foo 的包某个函数返回类型T时 ( T 并不是 Foo), 可以在函数名中加入类型信息

package

  • 只由小写字母组成。不包含大写字母和下划线等字符
  • 简短并包含一定的上下文信息。例如 schema、 task 等
  • 不要与标准库同名。例如不要使用 sync 或者 strings 以下规则尽量满足, 以标准库包名为例
  • 不使用常用变量名作为包名。例如使用 bufio 而不是 buf
  • 使用单数而不是复数。例如使用 encoding 而不是 encodings
  • 谨慎地使用缩写。例如使用 fmt 在不破坏上下文的情况下比 format 更加简短

小结

重点是减低阅读成本,考虑上下文信息,设计简洁清晰的名称。

性能分析工具pprof实战

这里课程采用了之前pprof给的一个实例,我们运行之后会占用一个端口方便我们查看程序运行的情况。

func main() {
   log.SetFlags(log.Lshortfile | log.LstdFlags)
   log.SetOutput(os.Stdout)

   runtime.GOMAXPROCS(1)
   runtime.SetMutexProfileFraction(1)
   runtime.SetBlockProfileRate(1)

   go func() {
      if err := http.ListenAndServe(":6060", nil); err != nil {
         log.Fatal(err)
      }
      os.Exit(0)
   }()

   for {
      for _, v := range animal.AllAnimals {
         v.Live()
      }
      time.Sleep(time.Second)
   }
}
终端命令

跑起来之后可以在终端运行

go tool pprof "http://localhost:6060/debug/pprof/profile?seconds=10"

top命令

可以看到如下的界面,可以看到是tiger.Eat耗时最长 image.png

image.png

Flat==Cum

当前函数没有调用其他函数

Flat ==0

当前函数值仅仅只调用了其他函数

web命令

这里需要安装graphviz才能看到图形化界面

性能调优案例分袖

性能分析工具