Go 代码审查:检查什么以及如何提供反馈

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

Go 代码审查:检查什么以及如何提供反馈



代码审查不仅仅是一种形式,更是开发过程中至关重要的环节。尤其是在 Go 语言中,代码的简洁性和可读性已深深植根于语言的设计哲学。对于初学者来说,这可能会令人望而生畏:如果自己都还没把握,该如何去批评别人的代码呢?实际上,代码审查是最好的学习方式。在本文中,我们将探讨审查 Go 代码时应关注哪些方面,以及如何提供既有用又不伤人的反馈。



1. 基本原则:首先检查什么



在深入细节之前,请记住一条黄金法则:审查针对的是代码,而不是人。你的目标是发现潜在问题并提高产品质量,而不是证明你比别人聪明。从简单的事情开始:



  • 逻辑错误:边界情况是否处理正确?例如,如果切片为空会发生什么?
  • 潜在的 panic:你是否忘记了 nil?检查是否在空指针上调用了方法。
  • 未使用的代码:在 Go 中,这会导致编译错误,但有时会遗留无用的变量或导入。


新手常见错误示例:



func getFirstElement(s []int) int {    return s[0] // 如果切片为空,会 panic!}


在审查中应该建议:添加切片长度检查并返回错误。



func getFirstElement(s []int) (int, error) {    if len(s) == 0 {        return 0, fmt.Errorf("slice is empty")    }    return s[0], nil}


2. Go 惯用写法:如何写出“地道的 Go 代码”



Go 不是 Java,也不是 Python。它有自己需要尊重的风格。在审查时,请注意以下几点:



  • 命名:Go 中习惯使用短名称(例如,r 表示 reader,w 表示 writer)。不要将变量命名为 myReader——只需用 r。
  • 错误处理:不要忽略错误!如果函数返回 error,就必须检查它。例外情况是 fmt.Println 之类的函数,但最好还是记录日志。
  • 接口:接口应该很小。一个方法很好,两个就有点多了。不要创建“以备将来之需”的接口。


“不地道”的 Go 代码示例:



func ProcessData(data []string) (bool, error) {    var result bool    for _, item := range data {        if item == "error" {            result = false            return result, errors.New("found error")        }    }    result = true    return result, nil}


这里的 result 是不必要的——可以直接返回 true 或 false。同时,应该使用 fmt.Errorf 进行格式化。



func ProcessData(data []string) (bool, error) {    for _, item := range data {        if item == "error" {            return false, fmt.Errorf("found error in item: %s", item)        }    }    return true, nil}


3. 性能与内存:需要注意什么



尽管 Go 足够快,但糟糕的代码可能会毁掉一切。在审查时,请检查:



  • 避免不必要的内存分配:如果你知道切片的大小,请使用带 capacity 参数的 make。
  • 结构体拷贝:较大的结构体最好通过指针传递,以避免每次拷贝。
  • Goroutine:检查是否忘记了关闭通道或等待 goroutine 完成(使用 sync.WaitGroup)。


切片使用不当的示例:



func appendItems(items []int) []int {    var result []int    for _, v := range items {                

博客

书籍推荐