[笔记] Go Code Review Comments

less than 1 minute read

阅读了官方的 code review 建议文档,将其中有启发的或是此前未曾听过的观点记录下来。

声明空切片 比起 t := []string{} 更推荐使用 var t []string。前者不是 nil,后者是 nil。它们在功能上是等价的:len 和 cap 都是0。 例外:当需要编码为 JSON 时,推荐用前者,因为它不会被编码为 null,而是空的 JSON 数组。

error 字符串 error 的字符串一般应该小写字母开头,而且不要以标点符号结尾。因为它们通常会作为其他字符串的一部分,比如放在一行日志中,如果以大写字母开头或者以标点符号结尾的话,看起来会很奇怪。

Goroutine 的生命周期 发起 goroutine 时, 确保阐述清楚它什么时候或者是否会退出。

空白引用 空白引用(import _ "pkg")应该只被用在 main 包或者测试中。

Mixed Caps Go 命名中不用下划线,用 mixedCaps 或者 MixedCaps 形式,即使对于常量也是如此。

Pass Values 不要仅仅为了节省几个字节就把传递指针作为函数参数。如果在一个函数里,参数 x 一直是作为 *x 被引用的,那这个参数就不应该是一个指针。 当然,大的结构体是个例外。

Receiver Names 一般比较短,一两个字母即可。要在对象的各个方法之间保持一致性。

Receiver Type 使用值还是指针作为方法的接收者,不是一个简单的问题,尤其对于新手来说。 如果不确定,就使用指针。 记住以下几点指导方针:

  • 接收者是 map,func,chan,不要使用指针
  • 接收者是 slice,并且方法里没有对该切片做 reslice或者reallocate,也不要使用指针
  • 方法中修改了接收者,那接收者必须是指针
  • 接收者是包含了 sync.Mutex 或者类似的同步域的结构体,则必须是指针,防止值的拷贝
  • 接收者是一个大结构体或者大数组,使用指针会更有效率些。那么多大才叫大呢?想象下将该结构体的所有元素作为参数传给方法,如果这样感觉太大了,那么它作为接收者也太大了
  • 方法外部是否会对接收者做更改,并且这个更改要对方法内可见? 如果是,那么就要使用指针。
  • 接收者是包含有指针元素的结构体、数组或者切片,并且该指针指向的对象会被改变,那么也建议使用指针作为接收者,这样可以更加明显地将这个“方法内部会改变对象”的意图传达给读代码的人
  • 如果接收者是一个小的数组或结构体,并且没有可变的域,没有指针在内,或者就是基本类型,比如int,string,那么使用值作为接收者。值接收者可以减少垃圾garbage,因为值的复制是发生在栈上的,不用在堆上分配内存。

Synchronous Functions 使用同步函数而不是异步函数。因为同步函数内部管理了 goroutine(如果有的话),有助于避免泄露和数据竞争,也更容易测试。

Tags:

Categories:

Updated:

Comments