go 命名惯例
go 语言的命名哲学就是尽可能的简单化。
go 要求的简单,不仅仅是简单化,还要关注上下文的连贯性,go 喜欢一个简洁明了的命名+对字段的注释
// userTypeInfo stores the information associated with a type the user has handed
// to the package. It's computed once and stored in a map keyed by reflection
// type.
type userTypeInfo struct {
user reflect.Type // the type the user handed us
base reflect.Type // the base type after all indirections
indir int // number of indirections to reach the base type
externalEnc int // xGob, xBinary, or xText
externalDec int // xGob, xBinary or xText
encIndir int8 // number of indirections to reach the receiver type; may be negative
decIndir int8 // number of indirections to reach the receiver type; may be negative
}
比如这段代码,对于字段和结构体都进行了注释,但是结构体内部的字段都相对简洁
包
包名称一般使用小写单词进行命名,例如说:context
,http
,net
,无需考虑包名称的重复化,因为在 go 引入包的过程中,实际上是引入的路径,并且 go 的包在引入过程中还可以进行包的重命名
import (
"example.com/hey/log"
blog "example.net/bob/log"
)
包的路径名称最后一位尽量和包的名称保持一致性,不过不一致也是有不少情况的,比如说,现在有一个适应不同语言的 log,那么命名的时候就变成了 github.com/shgopher/golog
,github.com/shgopher/javalog
,但是他们实际上的包都叫 log,并不是 golog 和 javalog,那么使用的时候就需要对其中一个包进行重命名了。
变量,类型,函数,方法
因为 go 语言使用导出的变量时需要带上包的名称 (除了。省略包名称的方式,一般不提倡),所以命名的时候变量不需要再加上包的称呼,比如说 string 包的 Reader 就不需要写成 string.StringReader
,写成 string.Reader
即可
go 变量的命名使用驼峰的命名方式,go 的文件名称使用下划线连接的方式,比如说 UpperName
,lowName
区别就是前者是大驼峰,导出的变量,后者是小驼峰,不可导出变量,缩略词如果首字母大写那么全部大写,比如 HTTP
,不能写成 Http
go 代码里使用了大量单字母或者短字母的命名方式。
for 循环中以及 if 条件语句中使用单字母
for k,v := range users{
}
if err := method1();err != nil {
}
函数和方法的参数或者返回值,常见单字母或单个单词的方式出现。
func method1(name string){}
方法调用的时候会绑定类型信息,可以尽量使用单个单词的命名方法
函数和类型多以多单词驼峰的方法组合,比如 func MakeFile(){}
,type gobEncoderType struct {}
在命名变量的时候,不要带上类型信息,比如说 names
比 nameSlice
要好,因为 go 强调命名和使用越近越好,没必要在字段上加上类型的名称。
go 使用一致性来强调单字母或者单个单词的意义,意思就是说使用的单个字母在任何地方表示的意思都是一样的。
for k,v := range names{}
for i,v := range users{}
从 k v i 这三个字母就可以观察到,绝大多数情况下,在 go 语言中 kv 就是表示的 key 和 value,i 表示的就是 index,那么即便是单个字母也不会造成识别障碍
另外 t
b
n
也很常见,他们通常表示 time 和 byte 以及数量
常量
- go 语言的常量并不要求全大写,通常只有本身是全大写的常量才是全大写,比如
PI
- 常量不需要赋予类型,系统会根据根据使用时期左变量的类型,以及运算操作进行自动推断
一般常量
const(
keepHostHeader = false
)
全大写常量
const PI = 3.14
const SIGABRT = Signal(0x6)
接口
拥有唯一方法的接口,或者内嵌多个拥有唯一方法的接口一律使用 单词+er
结尾,比如 Reader
或者 WriteReadCloser
go 语言推崇简单接口,和内嵌多个简单接口的接口,所以你会看到 go 语言标准库很多带有 er 结尾的接口
type Reader interface{
Reade()
}
type Writer interface{
Write()
}
type WriteReadeCloser interface{
Writer
Reader
Closer
}
两种命名的对比
简洁的并且考虑上下文一致性的代码:
func RuneCount(b []byte)int{
count := 0
for i:= 0;i< len(b);{
if b[i] < RuneSelf {
i++
} else{
_,n := DecodeRune(b[i:])
i+=n
}
count++
}
return count
}
见名知意的 java 式的代码:
func RuneCount(buffer []byte)int{
runeCount := 0
for index := 0;index < len(buffer);{
if buffer[index] < runeSelf {
index++
} else {
_, size := DecodeRune(buffer[index:])
index += size
}
runeCount++
}
return runeCount
}
参考资料
- 图书:go 语言精进之路