"编码规范(Go)"规范为日常Go项目开发提供一个统一的规范指导, 方便团队形成统一的代码风格, 提高代码可读性, 规范性和一致性.
同时作为CR的有效指导工具, 如果有变更的, 需要补充的, 可以在文档中(文档下)添加评论说明进行补充.
大部分的格式问题可以通过gofmt解决,gofmt自动格式化代码,保证所有的go代码与官方推荐的格式保持一致,于是所有格式有关问题,都以gofmt的结果为准。
目录
一. 命名规范
1 . 包命名
2. 文件命名
3. 方法命名(typespec - request, response)
4. 结构体命名
5. 接口命名
6. 变量命名
7. 常量命名
8. 关键字
二. 注释
1. 注释风格
2. 包注释
3. 结构体(接口)注释
4. 函数(方法)注释
5. 代码逻辑注释
三. 其他规范
1 . Error命名规范
2 . import 规范
四. 编程建议
1. Get方法
2. New方法
3. 错误处理
4. 空行建议
5. 一致性
6. 减少嵌套
五. 其他编码规范参考
命名是代码规范中很重要的一部分,统一的命名规则有利于提高的代码的可读性,好的命名仅仅通过命名就可以获取到足够多的信息。
Go在命名时以字母a到Z或a到Z或下划线开头,后面跟着零或更多的字母、下划线和数字(0到9)。Go不允许在命名时中使用@、$和%等标点符号。Go是一种区分大小写的编程语言。因此,Manpower和manpower是两个不同的命名。
保持package的名字和目录保持一致,尽量采取有意义的包名,简短,有意义,尽量和标准库不要冲突。包名应该为小写单词,不要使用下划线或者混合大小写。
net/url
,而不是net/urlsh
Bad |
Good |
---|---|
|
|
尽量采取有意义的文件名,简短,有意义.
其中测试文件以test.go结尾,除测试文件外,命名不出现
社区惯例是 不使用下划线(除非是测试文件)
但是业务项目,命名往往比较复杂、冗长,不用下划线的话,对代码阅读是个灾难
所以建议我们使用下划线进行分割, 这部分需要最终确认
3. 方法命名(typespec - request, response)
MixedCaps
方法名、函数名、变量、常量等标识符的命名,我们遵循Go社区关于使用 MixedCaps (可导出-大驼峰, 不可导出-小驼峰) 的约定。
有一个例外,为了对相关的测试用例进行分组,函数名可能包含下划线,如:TestMyFunction_WhatIsBeingTested.
关于缩写 名称中的缩写词或首字母缩写词(例如"URL"或"NATO")具有一致的大小写。
例如,"URL"应显示为"URL"或"url"(如在"urlPony"或"URLPony"中),而不应显示为"Url"。
对于包含多个缩写的标识符,也应当保遵守这个规则,例如:"xmlHTTPRequest"或"XMLHTTPRequest"。
https://github.com/golang/go/wiki/CodeReviewComments#mixed-caps
(This applies even when it breaks conventions in other languages. For example an unexported constant is maxLength
not MaxLength
or MAX_LENGTH
.)
方法名应该是动词或动词短语(动词+名词)
,采用驼峰式。将功能及必要的参数体现在名字中, 不要嫌长, 如updateById,getUserInfo.
Bad |
Good |
---|---|
|
|
4. 结构体命名
结构体名应该是名词或名词短语,如Account,Book,避免使用Manager这样的
|
5.
接口命名单个函数的接口名以 er 为后缀
|
两个函数的接口名综合两个函数名,如:
|
三个以上函数的接口名类似于结构体名,如:
|
6.
变量命名和结构体类似,变量名称一般遵循驼峰法,首字母根据访问控制原则大写或者小写,但遇到特有名词时,需要遵循以下规则:
|
7. 常量
命名常量均需使用MixedCaps命名方式,并使用下划线分词:
|
如果是枚举类型的常量,需要先创建相应类型
|
8. 关键字
下面的列表显示了Go中的保留字。这些保留字不能用作常量或变量或任何其他标识符名称
|
注释虽然写起来很痛苦, 但对保证代码可读性至关重要. 下面的规则描述了如何注释以及在哪儿注释.
当然也要记住: 注释固然很重要, 但最好的代码应当本身就是文档.
有意义的类型名和变量名, 要远胜过要用注释解释的含糊不清的名字.
你写的注释是给代码读者看的, 也就是下一个需要理解你的代码的人. 所以慷慨些吧, 下一个读者可能就是你!
|
|
|
|
使用MixedCaps或者mixedCaps的形式, 以Err开头
Bad |
Good |
---|---|
|
|
|
|
|
Bad |
Good |
---|---|
|
|
|
Go不提供对Get方法和Set方法的自动支持。你自己提供Get方法和Set方法是没有错的,通常这么做是合适的。但是,在Get方法的名字中加上Get,是不符合语言习惯的,并且也没有必要。如果你有一个域叫做owner(小写,不被导出),则Get方法应该叫做Owner(大写,被导出),而不是GetOwner。对于要导出的,使用大写名字,提供了区别域和方法的钩子。Set方法,如果需要,则可以叫做SetOwner。这些名字在实际中都很好读:
|
当包里只有一个对象时,比如gin包,New方法可以直接写成gin.New(),而不是gin.NewEngine()
空行有什么了不起,值得上升到规范的高度吗?是的,空行是一个小小的细节,但又不仅是一个细节问题
计算机并不需要空行, 都可以根据我们写的代码准确的执行
但由于人类大脑天性所致, 大脑会认为同时发生的任何事物都存在某种联系, 并且将事物按某种逻辑模式组织起来
密密麻麻的一大坨代码会給人整体的观感带来无以名状的压力
一个简单的原则就是将概念相关的代码放在一起:相关性越强,彼此之间的距离应该越短
本文中概述的一些标准都是客观性的评估,是根据场景、上下文、或者主观性的判断;
但是最重要的是,保持一致.
一致性的代码更容易维护、是更合理的、需要更少的学习成本、并且随着新的约定出现或者出现错误后更容易迁移、更新、修复 bug
相反,在一个代码库中包含多个完全不同或冲突的代码风格会导致维护成本开销、不确定性和认知偏差。所有这些都会直接导致速度降低、代码审查痛苦、而且增加 bug 数量。
将这些标准应用于代码库时,建议在 package(或更大)级别进行更改,子包级别的应用程序通过将多个样式引入到同一代码中,违反了上述关注点。
相似的声明放在一组
Go 语言支持将相似的声明放在一个组内。
Bad |
Good |
---|---|
|
|
这同样适用于常量、变量和类型声明:
Bad |
Good |
---|---|
|
|
仅将相关的声明放在一组。不要将不相关的声明放在一组。
Bad |
Good |
---|---|
|
|
分组使用的位置没有限制,例如:你可以在函数内部使用它们:
Bad |
Good |
---|---|
|
|
代码应通过尽可能先处理错误情况/特殊情况并尽早返回或继续循环来减少嵌套。减少嵌套多个级别的代码的代码量。
Bad |
Good |
---|---|
|
|
不必要的 else
如果在 if 的两个分支中都设置了变量,则可以将其替换为单个 if。
Bad |
Good |
---|---|
|
|
7. 本地变量声明
如果将变量明确设置为某个值,则应使用短变量声明形式 (:=
)。
Bad |
Good |
---|---|
|
|
但是,在某些情况下,var
使用关键字时默认值会更清晰。例如,声明空切片。
Bad |
Good |
---|---|
|
|
我们都是站在巨人的肩膀上学习和成长, 编码规范(Go)参考了:
Uber Go Style Guide: https://github.com/xxjwxc/uber_go_guide_cn
Golang官方编码规范: https://github.com/golang/go/wiki/CodeReviewComments
[代码规范]Go语言编码规范指导: https://zhuanlan.zhihu.com/p/63250689