一、工程目录规范
1.合理规划目录,一个目录中只包含一个包(实现一个模块的功能),如果模块功能复杂考虑拆分子模块,或者拆分目录。
2.内部项目GOPATH建议指向多个工作目录。Go语言有两种工程模式:
(1) 一个项目一个workspac, 这种项目结构中,每一个工程有一个完整的workspace空间,互相隔离,go get命令默认会使用GOPATH中第1个workspace,优点:项目之间互相隔离。
(2)所有项目共用一个workspace。优点: 方便发布到github.com, 让第三方通过go get等工具获取。
内部项目,建议采用第一种工程结构。公开项目、提供给第三方集成的项目采用第二种项目结构。
二、命名规范
1.文件名必须为小写单词,允许加下划线‘_’组合方式,但是头尾不能为下划线。
2.目录名必须为全小写单词,允许加中划线‘-’组合方式,但是头尾不能为中划线。
3.包名必须全部为小写单词,无下划线,越短越好,不要与标准库重名。
4.函数名必须为大小写混排的驼峰模式,不允许出现下划线。
5.结构体名必须为大小写混排的驼峰模式,不允许出现下划线,可被包外部引用则首字母大写;如仅包内使用,则首字母小写。
6.常量&枚举名,推荐采用大小写混排的驼峰模式(Golang官方要求),不允许出现下划线。
7.参数名必须为大小写混排,且首字母小写,不能有下划线。
8.全局变量必须为大小写混排的驼峰模式,不允许出现下划线。首字母根据作为范围确定大小写。
9.局部变量名必须为大小写混排,且首字母小写,不能有下划线。
10.接口名必须为大小写混排,支持包外引用则首字母大写,仅包内使用则首字母小写。不能有下划线,整体必须为名词。
11.方法接收名必须为大小写混排,首字母小写。方法接收者命名要能够体现接收者对象。
三、代码格式化规范
1.提交代码之前,必须使用gofmt对代码进行格式化。
2.提交代码之前,必须使用golint对代码进行检查。
四、函数规范
1.函数参数个数不要超过5个。
2.函数返回值个数不要超过3个。
3.函数嵌入层次不要超过4层。
4.单个函数建议行数不要超过50行,单个文件500行,行字符数不要超过120个。
5.函数中要尽早return,一旦有错误发生,应立即返回退出该函数。
6.单个函数圈复杂度最好不要超过10,禁止超过15。可以通过gocyclo工具计算
五、包引用规范
1.使用goimports去掉无用的包引用
2.引用顺序为:标准库、程序自研、三方件库。
3.禁止使用相对导入。
六、注释规范
1.所有导出对象都需要注释说明其用途;非导出对象根据情况进行注释。必须时,应该说明值的取值范围,及默认值。
2.注释的单行长度不能超过 80 个字符。
3.注释需要紧贴对应的包声明和函数之前,不能有空行。
4.每个程序包都应该有一个包注释,一个位于package子句之前的块注释。
5.函数声明处注释描述函数功能、性能及用法,包括输入和输出参数、函数返回值、可重入的要求等;定义处详细描述函数功能和实现要点,如实现的简要步骤、实现的理由、设计约束等
七、值与指针(T/*T)的使用规范
1.基本类型传递时,尽量使用值传递。
2.如果传递 字符串 或者接口对象时,建议直接实例传递而不是指针传递。
3.如果是map、func、chan,那么直接用T。
4.如果是slice,method里面不重新reslice之类的就用T。
5.如果想通过method改变里面的属性,那么请使用*T。
6.如果是 struct ,并且里面包含了sync.Mutex之类的同步原语,那么请使用*T,避免copy。
7.如果是一个大型的struct或者array,那么使用*T会比较轻量,效率更高。
8.如果是struct、slice、array里面的元素是一个指针类型,然后调用函数又会改变这个数据,那么对于读者来说采用*T比较容易懂。
9.其它情况下,建议采用*T。
八、go语言特性相关规范
1.公共包内禁止使用panic,如果有panic需要内部recover并返回error。
2.一个文件只定义一个init函数,一个包内的如果存在多个init函数,各个init之间不能有任何的依赖关系。
3.如果函数存在多个返回的地方,则采用defer来完成如关闭资源、解锁等清理操作。
4.传递 channel 类型的参数时应该区分其是否只读或者只写。在在只发送场景中,传递channel类型限定为: c chan<- int;在只接收场景中,传递channel类型限定为: c <-chan int
5.确保对channel是否关闭做检查。禁止重复释放channel,否则会造成panic,程序异常终止。
6.禁止在 nil 和closed的channel上进行接收、发送和关闭,会造成panic。
7.make申请slice/map时,根据预估大小来申请合适内存。
8.字符串拼接优先考虑bytes.Buffer或者strings.Builder。
9.为高并发的轻量级任务处理创建协程池。
10.关闭channel的基本准则:
(1)不要在接收端关闭channel,因为发送端无法知道channel已经关闭,往已经关闭的channel继续发送数据会造成panic。
(2)有多个写入端时,不要在写入端关闭channel,因为其他写入端无法知道channel自己已经关闭。
(3)已关闭的channel只要有数据就可以读取,直到nil,不会产生panic。
参考:
1.
2.#pass-values