Go语言编码规范
命名规范
文件名
整个应用或包的主入口文件应当是
main.go或与应用名称简写相同.文件名如果包含多个单词通过下划线连接.
包名
包名应该简短、清晰、有意义, 应全部是小写字母, 不要使用下划线或者驼峰方式连接. Go 中很多项目的包的名字是一样的, 但包的路径必需唯一. 看看官方库中的例子, 宁愿多个单词直接相连, 也不使用下划线或者驼峰方式相连:
1 2 3 4/src/cmd/addr2line /src/cmd/objdump /src/image/internal/imageutil /src/index/suffixarray包名必须和目录名一致, 尽量采取有意义、简短的包名, 不要和标准库冲突.
包名以及包所在的目录名, 不要使用复数, 例如: 应该是
net/url, 而不是net/urls.项目名可以看作是特殊的包名, 可以通过中划线来连接多个单词.
常量
常量名必须遵循驼峰式, 首字母根据访问控制决定使用大写或小写.
如果是枚举类型的常量, 需要先创建相应类型:
1 2 3 4 5 6type Scheme string const ( HTTP Scheme = "http" HTTPS Scheme = "https" )
变量
变量为单独的单词时, 可导出变量开头字母大写, 私有变量全小写; 专有名词时, 可导出变量全大写, 私有变量时全小写.
多单词组成的变量名称遵循驼峰法, 可导出(公有)变量开头字母要大写, 不可导出(私有)变量开头字母小写. 比如: 可导出变量为
UserName, 对应私有变量为userName. 不过对于专有名词, 比如 API、ID、HTTP、IP 等, 需要这样处理, 举例: 私有变量 apiClient, 对应可导出变量为 APIClient.常见的专有名词列表:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36// A GonicMapper that contains a list of common initialisms taken from golang/lint var LintGonicMapper = GonicMapper{ "API": true, "ASCII": true, "CPU": true, "CSS": true, "DNS": true, "EOF": true, "GUID": true, "HTML": true, "HTTP": true, "HTTPS": true, "ID": true, "IP": true, "JSON": true, "LHS": true, "QPS": true, "RAM": true, "RHS": true, "RPC": true, "SLA": true, "SMTP": true, "SSH": true, "TLS": true, "TTL": true, "UI": true, "UID": true, "UUID": true, "URI": true, "URL": true, "UTF8": true, "VM": true, "XML": true, "XSRF": true, "XSS": true, }若变量类型为
bool类型, 则名称应以Has,Is,Can或Allow开头, 例如:1 2 3 4var hasConflict bool var isExist bool var canManage bool var allowGitHook bool
函数或方法名
命名规则基本遵从变量的命名规则.
函数尽量少用全局变量, 应该通过参数传递, 使每个函数都是"无状态"的, 减少耦合, 方便分工和单元测试; 如果函数参数比较多, 可以将相关参数定义成结构体传递.
结构体名
- 结构体名不应该是动词, 应该是名词.
- 其他命名规则同变量的命名规则.
接口名
为了更方便区分, 可导出接口名前统一加大写
I, 私有接口名前统一加小写i, 然后紧跟具体对象名称的大写字母, 比如:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15// 可导出接口 type IDemo interface { Create() Update() Get() Delete() } // 私有接口 type iDemo interface { Create() Update() Get() Delete() }
import 包导入规范
一个源代码文件导入的包(package)可以分为 4 类:
- 标准库(
package) - 第三方库(
package) - 组织内(公司内)其他项目的包(
package) - 当前项目的子包(
package)
导入规范:
每类之间使用空行分隔
不要使用
.来导入包不要使用相对路径导入子包(比如:
../subpackage), 示例:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20import ( // 标准库 "fmt" "html/template" "net/http" "os" // 第三方库 "github.com/codegangsta/cli" "gopkg.in/macaron.v1" // 组织内或公司内其他项目的包 "github.com/gogits/git" "github.com/gogits/gfm" // 当前项目的子包 "github.com/gogits/gogs/routers" "github.com/gogits/gogs/routers/repo" "github.com/gogits/gogs/routers/user" )
注释规范
所有导出对象(大写字母开头)都需要注释说明其用途, 非导出对象根据复杂情况进行选择性注释.
包、函数、方法和类型的注释说明需要是一个完整的句子, 句子类型的注释首字母均需大写, 短语类型的注释首字母需小写.
注释的单行长度不要超过
120个字符.只使用单行注释符号
//, 尽量不使用多行注释符号/* */.包级别的注释就是对包的介绍, 只需在同个包的任一源文件中说明即可有效.
当某个部分等待完成时, 可用
TODO:开头的注释来提醒维护人员.当某个部分存在已知问题进行需要修复或改进时, 可用
FIXME:开头的注释来提醒维护人员.当需要特别说明某个问题时,可用
NOTE:开头的注释.在多段注释之间可以使用空行分隔加以区分, 如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14// WithCancel returns a copy of parent with a new Done channel. The returned // context's Done channel is closed when the returned cancel function is called // or when the parent context's Done channel is closed, whichever happens first. // // Canceling this context releases resources associated with it, so code should // call cancel as soon as the operations running in this Context complete. func WithCancel(parent Context) (ctx Context, cancel CancelFunc) { if parent == nil { panic("cannot create context from nil parent") } c := newCancelCtx(parent) propagateCancel(parent, &c) return &c, func() { c.cancel(true, Canceled) } }包注释, 包注释统一用
//进行注释, 格式为// Package 包名 包描述, 例如:1 2 3 4// Package context defines the Context type, which carries deadlines, // cancellation signals, and other request-scoped values across API boundaries // and between processes. package context
函数或方法定义规范
函数或方法的顺序一般需要按照依赖关系排序, 被依赖的函数放到前面.
函数参数传入变量和返回变量都以小写字母开头.
传入参数数量不能超过 5 个, 超过则使用
struct替代.多返回值最多返回 3 个, 超过三个请使用
struct.应以对象第一个英文首字母的小写作为方法接收器的名称, 不要使用
me、this、self.函数或方法的顺序一般需要按照依赖关系排序, 被依赖的函数放到前面.
结构附带的方法应置于结构定义之后, 按照所对应操作的字段顺序摆放方法.
如果一个结构拥有对应操作函数, 大体上按照
CRUD(增查改删) 的顺序放置结构定义之后.如果一个结构拥有以
Has、Is、Can或Allow开头的函数或方法,则应将它们置于所有其它函数及方法之前.如果函数被一个变量引用作为一部分, 函数应该放到这个变量之后.
其他规范
单行代码不要超过
120个字符, 如果超过需要进行分行.变量声明尽量放在变量第一次使用的前面, 遵循就近原则.
如果魔法数字出现超过两次, 则禁止使用, 改用一个常量代替.
分组声明一般需要按照功能来区分, 而不是将所有类型都分在一组.
其他规范细节建议详细阅读: https://github.com/xxjwxc/uber_go_guide_cn
参考:
https://golang.org/doc/code.html#PackageNames
https://golang.org/doc/effective_go.html#package-names
https://golang.org/doc/code.html
https://golang.org/doc/effective_go.html
https://github.com/unknwon/go-code-convention/blob/master/zh-CN/README.md