编写更加清晰整洁的代码
高质量编程简介
高质量是一个相对主观的概念。主要有这几方面
- 各种边界条件是否完备
- 异常情况处理是否完备
- 易读易维护
编程原则
- 简单性:消除多余的复杂性,以简单清晰的逻辑编写代码。
- 可读性:编写可维护代码的第一步是可读
- 生产力:团队的整体效率
编程规范
编写高质量的Go代码
公共符号始终要注释
- 包中声明的每个公共的符号: 变量、常量、函数以及结构都需要添加注释
- 任何既不明显也不简短的公共功能必须予以注释
- 无论长度或复杂程度如何, 对库中的任何函数都必须进行注释
代码格式
使用gofmt自动格式化,GoLand可以自动格式化
注释
注释应该做的
- 注释应该解释代码作用
- 注释应该解释代码如何做的
- 注释应该解释代码实现的原因
- 注释应该解释代码什么情况会出错
变量命名规范
变量
简洁胜于冗长 缩略词全大写,但当其位于变量开头且不需要导出时,使用全小写
- 例如使用 ServeHTTP 而不是 ServeHttp
- 使用 XMLHTTPRequest 或者 xmIHTTPRequest 变量距离其被使用的地方越远,则需要携带越多的上下文信息
- 全局变量在其名字中需要更多的上下文信息, 使得在不同地方可以轻易辩认出其含义
这个例子是函数参数的名称示例,为了简短将时间参数 deadline 改成了 t t 常代指任意时间 deadline 指截止时间,有特定的含义 函数提供给外部调用时,签名的信息很重要,要将自己的功能准确表现出来,自动提示一般也会提示函数的方法签名,通过参数名更好的理解功能很有必要,节省时间
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耗时最长
Flat==Cum
当前函数没有调用其他函数
Flat ==0
当前函数值仅仅只调用了其他函数
web命令
这里需要安装graphviz才能看到图形化界面