Explosive liver sharing two thousand words Go programming specification

Get into the habit of writing together! This is the 10th day of my participation in the "Nuggets Daily New Plan · April Update Challenge", click to view the details of the event .

Today's article is standing on the shoulders of giants, summarizing the current mainstream development specifications, and combining the characteristics of the Go language and my own project experience: 爆肝分享两千字Go编程规范.

More elegant specifications will be updated in the future.

naming style

1. [Mandatory] Names in the code cannot start with an underscore or dollar sign, and cannot end with an underscore or dollar sign. 

Counter example:  _name / __name / $name / name_ / name$ / name__  

2. [Mandatory] It is strictly forbidden to mix Pinyin and English for the naming in the code, and it is not allowed to use Chinese directly. 

Description: Correct English spelling and grammar can make it easy for readers to understand and avoid ambiguity.

Note that pure pinyin naming should be avoided. 

Positive example: renminbi / alibaba / taobao / youku / hangzhouother international names can be regarded as the same as English.

Counter example:DaZhePromotion [ 打 折 ] / getPingfenByName() [评分] / int某变量 = 3

 

UpperCamelCase3. [Mandatory] Use the naming style of common variables, types, interfaces, structures, functions, and member variables of structures .

Normal example:GolangStruct / UserDO / XmlService / TcpUdpDeal / TaPromotion

Counterexample:Golangstruct / UserDo / XMLService / TCPUDPDeal / TAPromotion

 

4. [Mandatory] Private variables, types, interfaces, structures, functions, parameter names, and local variables all use the lowerCamelCase style and must follow the camel case.

Correct example:localValue / getHttpMessage() / inputUserId

 

5. [Mandatory] Use the UpperCamelCase style for the naming of constants, and use const declaration to make the semantic expression complete and clear, and don't think the name is too long.

Normal example:const StatusOK = 200

 

6. The abstract structure name starts with Abstract or Base; the exception class name starts with Err; the test class name starts with Test and ends with the name of the function to be tested.

Correct example: ParamsErr := errors.New(“params err”)

 

7. The interface naming convention generally ends with er: the interface name of a single function is suffixed with "er", and the implementation of the interface removes er; the interface names of two functions combine the two function names, with er as the suffix, and the implementation of the interface is Remove er; the interface of more than three functions, abstract the function of this interface, similar to the structure naming.

 

8. 【强制】数据和切片类型命名以 Arr 结尾,map 类型以 Map 结尾。相同功用的结构体可以根据功能采 用相同的结尾, Api 请求以 Req 结尾, 相应以 Res 结尾,数据结构体以 xxxModel 结尾, xxx 即为数据表名。

正例:var userArr [3]string / type LoginReq struct{} / type UserDO struct{}

 

9. 【强制】返回结果主要为布尔类型的函数,函数名可以 is、has 等开头

10. 【强制】工程名统一使用小写,单词之间使 用 - 分割。包目录名一律使用小写,尽量采用一 个单词命名,单词间不用符号分割,统一使用单 数形式,但是结构体名如果有复数含义,结构体 名可以使用复数形式。包目录下的包名( package namepackage ),如非 main 函数,和包目录名保持一直且单词间用 _ 分隔,测试文件以 _test 结 尾。

正 例 : db-utils / package db_utils / package db_utils_test

反例:services

 

11. 为了达到代码自解释的目标,任何自定义编程元 素在命名时,使用尽量完整的单词组合来表达其意。反例:var a int 的随意命名方式。

 

12. 在常量与变量的命名时,表示类型的名词放在词尾,以提升辨识度。如规范【8】所示。

正例:startTime / startDate 反例:startedAt / startDt

 

13.如果模块、接口、类、方法使用了设计模式,在命名时需体现出具体模式。

说明:将设计模式体现在名字中,有利于阅读者 快速理解架构设计理念。

 

代码格式

1. 【强制】如果是大括号内为空,则简洁地写成{} 即可,大括号中间无需换行和空格;如果是非空 代码块则: 1) 左大括号前不换行。 2) 左大括号后换行。 3) 右大括号前换行。 4) 右大括号后还有 else 等代码则不换行;表 示终止的右大括号后必须换行。

2. 【强制】左小括号和字符之间不出现空格;同样, 右小括号和字符之间也不出现空格;而左大括号 前需要空格。 反例:if (空格 a == b 空格)

3. 【强制】if / for / switch 等保留字与括号之间都必 须加空格。

4. 【强制】任何二目、三目运算符的左右两边都需 要加一个空格。 说明:运算符包括赋值运算符= 、逻辑运算符&&、 加减乘除符号等。

5. 【强制】采用 tab 字符缩进,宽度设置为 4 个 空格

6. 【强制】单行字符数限制不超过 120 个,超出 需要换行,换行时遵循如下原则:

  1. 第二行相对第一行缩进一个 tab,从第三行 开始,不再继续缩进。
  2. 运算符与上文一起作为结尾。
  3. 方法调用的点符号与上文一起作为结尾。
  4. 方法调用中的多个参数需要换行时,在逗号 后进行。
  5. 在括号前不要换行

7.【强制】函数参数在定义和传入时,多个参数逗 号后边必须加空格。

 

控制语句

  1. 【强制】在一个 switch 块内,每个 case 无需声 明 break 来 终 止 , 如 果 想 顺 序 执 行 使 用 fallthrough ;在一个 switch 块内,都必须包含 一个 default 语句并且放在最后,即使它什么代 码也没有。

  2. 【强制】在高并发场景中,避免使用”等于”判 断作为中断或退出的条件。 说明:如果并发控制没有处理好,容易产生等值 判断被“击穿”的情况,使用大于或小于的区间 判断条件来代替。 反例:判断剩余奖品数量等于 0 时,终止发放 奖品,但因为并发处理错误导致奖品数量瞬间变成了负数, 这样的话,活动无法终止。

  3. 【推荐】表达异常的分支时,少用 if-else 方式, 这种方式可以改写成: if condition { … return obj; } // 接着写 else 的业务逻辑代码;

    说明:如果非使用 if()…else if()…else…方式表 达逻辑,避免后续代码维护困难,【强制】请勿 超过 3 层。

    正例:超过 3 层的 if-else 的逻辑判断代码可 以使用卫语句、策略模式、状态模式等来实现, 其中卫语句即代码逻辑先考虑失败、异常、中断、 退出等直接返回的情况,以方法多个出口的方 式,解决代码中判断分支嵌套的问题,这是逆向 思维的体现。

 

4. 【参考】下列情形,需要进行参数校验:

  1. 调用频次低的方法。
  2. 执行时间开销很大的方法。此情形中,参数 校验时间几乎可以忽略不计,但如果因为参数错 误导致中间执行回退,或者错误,那得不偿失。
  3. 需要极高稳定性和可用性的方法。
  4. 对 外 提 供 的 开 放 接 口 , 不 管 是 RPC/API/HTTP 接口。
  5. 敏感权限入口。

5. 【参考】下列情形,不需要进行参数校验:

  1. 极有可能被循环调用的方法。但在方法说明 里必须注明外部参数检查要求。

  2. 底层调用频度比较高的方法。毕竟是像纯净 水过滤的最后一道,参数错误不太可能到底层才 会暴露问题。一般 DAO 层与 Service 层都在 同一个应用中,部署在同一台服务器中,所以 DAO 的参数校验,可以省略。

杂项

1. 【强制】在使用正则表达式时,利用好其预编译 功能,可以有效加快正则匹配速度。 正例: // 预编译当前正则表达式re, _ := regexp.Compile("^hel+o") // 是否匹配指定字符串 isMatch := re.MatchString(“hello world”)

2. 【推荐】及时清理不再使用的代码段或配置信息。 说明:对于垃圾代码或过时配置,坚决清理干净, 避免程序过度臃肿,代码冗余。 正例:对于暂时被注释掉,后续可能恢复使用的 代码片断,在注释代码上方,统一规定使用三个 斜杠(///)来说明注释掉代码的理由。

异常日志

1. 【强制】使用控制流机制应对错误,通过从函数 返回错误作为附加返回值来指示错误,如果函数 有多个返回值,习惯上将错误值作为最后一个结 果返回。如果错误只有一种情况,结果通常设置为布尔类型。nil 值表示没有错误。 正例:res, err := somepkgAction()

2. 【强制】对于总是成功返回的函数,不必返回错误。

3. 【强制】错误信息的首字母小写且避免换行

更多

还会更新更多优雅的规范实践...

没有规矩不成方圆,团队开发中只有严格按照规范进行,才能避免开发一时爽,维护火葬场的困顿局面~

最后

感谢阅读,欢迎大家三连:点赞、收藏、coin(focus on)! ! !

8e95dac1fd0b2b1ff51c08757667c47a.gif

Guess you like

Origin juejin.im/post/7086094606856618014