Go语言规范汇总

目录

  • 统一规范篇
    • 合理规划目录
    • GOPATH设置
    • import 规范
    • 代码风格
    • 大小约定
  • 命名篇
    • 基本命令规范
    • 项目目录名
    • 包名
    • 文件名
    • 常量
    • 变量
      • 变量申明
      • 变量命名惯例
      • 全局变量名
      • 局部变量名
      • 循环变量
    • 结构体(struct)
    • 接口名
    • 函数和方法名
    • 参数名
    • 返回值
  • 开发篇
    • 魔鬼数字
    • 常量 & 枚举
    • 结构体
    • 运算符
    • 函数
    • 参数
    • 返回值
    • 注释
    • 错误
    • 其他
    • 参数传递
    • 注意闭包的调用
  • 优化篇
    • 质量保证
      • 代码质量保证优先原则
      • 对外接口原则
      • 值与指针(T/*T)的使用原则
      • init的使用原则
      • defer的使用原则
      • Goroutine使用原则
      • Channel使用原则
      • 其它
    • 性能效率
      • Memory优化
      • GC 优化
      • 其它优化建议

统一规范篇

合理规划目录

本篇主要描述了公司内部同事都必须遵守的一些开发规矩,如统一开发空间,既使用统一的开发工具来保证代码最后的格式的统一,开发中对文件和代码长度的控制,必须经过go语言自带的检测机制等。

【原则1.1】合理规划目录,一个目录中只包含一个包(实现一个模块的功能),如果模块功能复杂考虑拆分子模块,或者拆分目录。

GOPATH设置

【建议1.2】使用单一的 GOPATH

import 规范

【规则1.3.1】在非测试文件(*_test.go)中,禁止使用 . 来简化导入包的对象调用。

【规则1.3.2】禁止使用相对路径导入(./subpackage),所有导入路径必须符合 go get 标准。

【建议1.3.3】建议使用goimports工具或者IDE工具来管理多行import

代码风格

【规则1.4.1】提交代码时,必须使用gofmt对代码进行格式化。

【规则1.4.2】提交代码时,必须使用golint对代码进行检查。

【建议1.4.3】提交代码前,必须使用go vet对代码进行检查。

大小约定

【建议1.5.1】单个文件长度不超过500行。

【建议1.5.2】单个函数长度不超过50行。

【规则1.5.3】单个函数圈复杂度最好不要超过10,禁止超过15。

【规则1.5.4】单行语句不能过长,如不能拆分需要分行写。一行最多120个字符。

【建议1.5.5】函数中缩进嵌套必须小于等于3层。

【原则1.5.6】保持函数内部实现的组织粒度是相近的。

命名篇

本篇以开发时从上往下的顺序既:开发前约定的基本命名规范、包、常量、变量、结构体、参数、返回值的顺序讲解了开发中各个环节的命名规范。

基本命令规范

【规则2.1.1】需要注释来补充的命名就不算是好命名。

【规则2.1.2】使用可搜索的名称

【规则2.1.3】做有意义的区分

项目目录名

【规则2.2.1】目录名必须为全小写单词,允许加中划线‘-’组合方式,但是头尾不能为中划线。

【建议2.2.2】虽然允许出现中划线,但是尽量避免或少加中划线。

包名

【原则2.3.1】取名尽量采取有意义的包名,简单和可阅读。

【规则2.3.2】包名必须全部为小写单词,无下划线,越短越好。尽量不要与标准库重名。

【规则2.3.3】禁止通过中划线连接多个单词的方式来命名包名。

【建议2.3.4】包名尽量与所在目录名一致,引用时比较方便。

文件名

【规则2.4.1】文件名必须为小写单词,允许加下划线‘_’组合方式,但是头尾不能为下划线

【建议2.4.2】虽然允许出现下划线,但是尽量避免。

【建议2.4.3】文件名以功能为指引,名字中不需再出现模块名或者组件名。

常量

【规则2.5.1】常量&枚举名采用大小写混排的驼峰模式(Golang官方要求),不允许出现下划线

【建议2.5.2】按照功能来区分,而不是将所有类型都分在一组,并建议将公共常量置于私有常量之前

【规则2.2.3】如果是枚举类型的常量,需要先创建相应类型

【建议2.5.4】如果模块的功能较为复杂、常量名称容易混淆的情况下,为了更好地区分枚举类型,可以使用完整的前缀

变量

变量申明

【规则2.6.1】变量命名基本上遵循相应的英文表达或简写,在相对简单的环境(对象数量少、针对性强)中,可以将一些名称由完整单词简写为单个字母

变量命名惯例

【规则2.6.2】变量名称一般遵循驼峰法,并且不允许出现下划线,当遇到特有名词时,需要遵循以下规则:

  • 如果变量为私有,且特有名词为首个单词,则使用小写,如:apiClient
  • 其它情况都应当使用该名词原有的写法,如 APIClient、repoID、UserID

【规则2.6.3】不要使用_来命名变量名,多个变量申明放在一起

【规则2.6.4】在函数外部申明必须使用var,不要采用:=,容易踩到变量的作用域的问题。

全局变量名

【规则2.6.5】全局变量必须为大小写混排的驼峰模式,不允许出现下划线。首字母根据作为范围确定大小写。

【建议2.6.6】尽量避免跨package使用全局变量,尽量减少全局变量的使用。

局部变量名

【规则2.6.7】局部变量名必须为大小写混排,且首字母小写,不能有下划线。

循环变量

【建议2.6.8】for循环变量可以使用单字母。

结构体(struct)

【规则2.7.1】struct申明和初始化格式采用多行

【规则2.7.2】结构体名必须为大小写混排的驼峰模式,不允许出现下划线,可被包外部引用则首字母大写;如仅包内使用,则首字母小写。

【建议2.7.3】结构名建议采用名词、动名词为好。

接口名

【规则2.8.1】接口名必须为大小写混排,支持包外引用则首字母大写,仅包内使用则首字母小写。不能有下划线,整体必须为名词。

【建议2.8.2】单个函数的接口名以”er”作为后缀。

函数和方法名

【规则2.9.1】函数名必须为大小写混排的驼峰模式

【建议2.9.2】函数名力求精简准确,并采用用动词或动词短

【规则2.9.3】方法接收名必须为大小写混排,首字母小写。方法接收者命名要能够体现接收者对象。

【建议2.9.4】接收者名通常1个或者2个字母就够,最长不能超过4个字母。

【建议2.9.5】接收者名不要使用me,this 或者 self 这种泛指的名字。

【建议2.9.6】定义方法时,如果方法内不会直接引用接收者,则省略掉接收者名。

参数名

【规则2.10】参数名必须为大小写混排,且首字母小写,不能有下划线。

返回值

【规则2.11.1】返回值如果是命名的,则必须大小写混排,首字母小写。

【建议2.11.2】 函数的返回值应避免使用命名的参数。

开发篇

本篇主要是讲解开发中各个环节的开发规范和对一些代码的优化写法。在本文中有一些特别标黄的建议,我真的建议你好好看看那些代码,因为那可能对你提高代码开发会很有帮助。

【建议3.1.1】项目仓库中包含全量的代码

【建议3.1.2】建议采用 Glide 来管理第三方包

魔鬼数字

【规则3.2】代码中禁止使用魔鬼数字。

常量 & 枚举

【建议3.3.1】 为整数常量添加 String() 方法

【建议3.3.2】让 iota 从 a +1 开始增量

结构体

【规则3.4.1】对于要使用json转换的结构体代码,变量名必须为大写,否则你只会得到一个为空的对象

【建议3.4.2】 在初始化结构体时使用带有标签的语法

【建议3.4.3】将结构体的初始化拆分到多行

运算符

【规则3.5】运算符前后、逗号后面、if后面等需有单空格隔开。

函数

【原则3.6.1】保持函数内部实现的组织粒度是相近的。

【建议3.6.2】 返回函数调用

【建议3.6.3】 withContext 封装函数

参数

【建议3.7.1】参数按逻辑紧密程度安排位置, 同种类型的参数放在相邻位置。

【建议3.7.2】避免使用标识参数来控制函数的执行逻辑。

【建议3.7.3】参数个数不要超过5个

返回值

【规则3.8.1】函数返回值个数不要超过3个。

【建议3.8.2】如果函数的返回值超过3个,建议将其中关系密切的返回值参数封装成一个结构体。

注释

【原则3.9.1】编写代码首先考虑如何代码自我解释,然后才是添加注释进行补充说明

【原则3.9.2】注释的内容要清楚、明了,含义准确,防止注释二义性。

【原则3.9.3】在代码的功能、意图层次上进行注释,即注释用于解释代码难以直接表达的意图,而不是重复描述代码。

【规则3.9.4】所有导出对象都需要注释说明其用途;非导出对象根据情况进行注释。必须时,应该说明值的取值范围,及默认值。

【规则3.9.5】注释的单行长度不能超过 80 个字符。

【规则3.9.6】注释需要紧贴对应的包声明和函数之前,不能有空行、

【规则3.9.7】非跨度很长的注释,尽量使用 // 方式。

【规则3.9.8】避免多余的空格,两句注释之间保持一个空格。

【原则3.9.9】注释第一条语句应该为一条概括语句,并且使用被声明的名字作为开头。

【建议3.9.10】//与注释的文档之间空一格。

【规则3.9.11】每个程序包都应该有一个包注释,一个位于package子句之前的块注释。

【规则3.9.12】不要依靠用空格进行对齐。

【建议3.27】类型定义一般都以单数信息描述。

【建议3.9.13】函数声明处注释描述函数功能、性能及用法,包括输入和输出参数、函数返回值、可重入的要求等;定义处详细描述函数功能和实现要点,如实现的简要步骤、实现的理由、设计约束等

【建议3.9.14】如果函数或者方法为判断类型(返回值主要为bool类型),则以 returns true if 开头。

错误

【原则3.10.1】错误处理的原则就是不能丢弃任何有返回err的调用,不要采用_丢弃,必须全部处理。接收到错误,要么返回err,要么实在不行就panic,或者使用log记录下来

【规则3.10.2】error的信息不要采用大写字母,尽量保持你的错误简短,但是要足够表达你的错误的意思。

【规则3.10.3】导出的错误变量的命名,以Err开始,如ErrSomething,无需导出的错误变量命名,以Error作为后缀,如specificError

【规则3.10.4】公共包内禁止使用panic,如果有panic需要内部recover并返回error。

其他

【建议3.11.1】在代码中编写字符串形式的json时,使用反单引号,而不是双引号。

【规则3.11.2】相对独立的程序块之间、变量说明之后必须加空行,而逻辑紧密相关的代码则放在一起。

【规则3.11.3】尽早return:一旦有错误发生,马上返回。

【建议3.11.4】禁止出现2处及以上的重复代码。

【建议3.11.5】if条件判断, 同时使用超过3个表达式以上的时候, 使用switch替代。

【建议3.11.6】定义bool变量时,要避免判断时出现双重否定,应使用肯定形式的表达式。

【建议3.11.7】for循环初始值从0开始,判断条件使用<无等号的方式。

【建议3.11.8】长句子打印或者调用,使用参数进行格式化分行

【建议3.11.9】 将 for-select 封装到函数中

【建议3.11.10】把 slice、map 等定义为自定义类型

【建议3.11.11】 为访问 map 增加 setter,getters

参数传递

【建议3.11.12】 对于少量数据,不要传递指针

【建议3.11.13】 对于大量数据的 struct 可以考虑使用指针

【建议3.11.14】 传入的参数是 map,slice,chan 不要传递指针,因为 map,slice,chan 是引用类型,不需要传递指针的指针

注意闭包的调用

【原则3.11.15】在循环中调用函数或者goroutine方法,一定要采用显示的变量调用,不要再闭包函数里面调用循环的参数

优化篇

本篇的意义是为开发提供一些经过验证的开发规则和建议,让开发在开发过程中避免低级错误,从而提高代码的质量保证和性能效率

质量保证

代码质量保证优先原则

【原则4.1.1】代码质量保证优先原则:
(1)正确性,指程序要实现设计要求的功能。
(2)简洁性,指程序易于理解并且易于实现。
(3)可维护性,指程序被修改的能力,包括纠错、改进、新需求或功能规格变化的适应能力。
(4)可靠性,指程序在给定时间间隔和环境条件下,按设计要求成功运行程序的概率。
(5)代码可测试性,指软件发现故障并隔离、定位故障的能力,以及在一定的时间和成本前提下,进行测试设计、测试执行的能力。
(6)代码性能高效,指是尽可能少地占用系统资源,包括内存和执行时间。
(7)可移植性,指为了在原来设计的特定环境之外运行,对系统进行修改的能力。

对外接口原则

【原则4.1.2】对于主要功能模块抽象模块接口,通过interface提供对外功能。

值与指针(T/*T)的使用原则

【建议4.1.3.1】基本类型传递时,尽量使用值传递。

【建议4.1.3.2】如果传递字符串或者接口对象时,建议直接实例传递而不是指针传递。

【建议4.1.3.3】如果是map、func、chan,那么直接用T。

【建议4.1.3.4】如果是slice,method里面不重新reslice之类的就用T。

【建议4.1.3.5】如果想通过method改变里面的属性,那么请使用*T。

【建议4.1.3.6】如果是struct,并且里面包含了sync.Mutex之类的同步原语,那么请使用*T,避免copy。

【建议4.1.3.7】如果是一个大型的struct或者array,那么使用*T会比较轻量,效率更高。

【建议4.1.3.8】如果是struct、slice、array里面的元素是一个指针类型,然后调用函数又会改变这个数据,那么对于读者来说采用*T比较容易懂。

【建议4.1.3.9】其它情况下,建议采用*T。

init的使用原则

【规则4.1.4.1】一个文件只定义一个init函数。

【规则4.1.4.2】一个包内的如果存在多个init函数,不能有任何的依赖关系。

defer的使用原则

【建议4.1.5.1】如果函数存在多个返回的地方,则采用defer来完成如关闭资源、解锁等清理操作。

【建议4.1.5.2】defer会消耗更多的系统资源,不建议用于频繁调用的方法中。

【建议4.1.5.3】避免在for循环中使用defer。

Goroutine使用原则

【规则4.1.6.1】确保每个goroutine都能退出。

【规则4.1.6.2】禁止在闭包中直接引用闭包外部的循环变量。

Channel使用原则

【规则4.1.7.1】传递channel类型的参数时应该区分其职责。

【规则4.1.7.2】确保对channel是否关闭做检查。

【规则4.1.7.3】禁止重复释放channel。

其它

【建议4.1.8.1】使用go vet --shadow检查变量覆盖,以避免无意的变量覆盖。

【建议4.1.8.2】GO的结构体中控制使用Slice和Map。

【规则4.1.8.3】避免在循环引用调用 runtime.SetFinalizer。

【规则4.1.8.4】避免在for循环中使用time.Tick()函数。

性能效率

Memory优化

【建议4.2.1.1】将多次分配小对象组合为一次分配大对象。

【建议4.2.1.2】将多个不同的小对象绑成一个大结构,可以减少内存分配的次数。

【建议4.2.1.3】组合内存分配的一个特殊情形是对分片数组进行预分配。

【建议4.2.1.4】尽可能使用小数据类型,并尽可能满足硬件流水线(Pipeline)的操作,如对齐数据预取边界。

【建议4.2.1.5】使用对象池来重用临时对象,减少内存分配。

GC 优化

【建议4.2.2.1】设置GOMAXPROCS为CPU的核心数目,或者稍高的数值。

【建议4.2.2.2】避免频繁创建对象导致GC处理性能问题。

其它优化建议

【建议4.2.3.1】减少[]byte和string之间的转换,尽量使用[]byte来处理字符。

【建议4.2.3.2】make申请slice/map时,根据预估大小来申请合适内存。

【建议4.2.3.3】字符串拼接优先考虑bytes.Buffer。

【建议4.2.3.4】避免使用CGO或者减少跨CGO调用次数。

【建议4.2.3.5】避免高并发调用同步系统接口。

【建议4.2.3.6】高并发时避免共享对象互斥。

【建议4.2.3.7】长调用链或在函数中避免申明较多较大临时变量。

【建议4.2.3.8】为高并发的轻量级任务处理创建routine池。

【建议4.2.3.9】建议版本提供性能/内存监控的功能,并动态开启关闭,但不要长期开启pprof提供的CPU与MEM profile功能。

转载于:https://www.cnblogs.com/Survivalist/articles/10596152.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/387159.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

3.14 01串排序

将01串首先按照长度排序&#xff0c;其次按1的个数的多少排序&#xff0c;最后按ASCII码排序。 输入样例&#xff1a; 10011111 00001101 10110101 1 0 1100 输出样例&#xff1a; 0 1 1100 1010101 00001101 10011111 #include<fstream> #include<iost…

platform(win32) 错误

运行cnpm install后&#xff0c;出现虽然提示不适合Windows&#xff0c;但是问题好像是sass loader出问题的。所以只要执行下面命令即可&#xff1b;方案一&#xff1a;cnpm rebuild node-sass #不放心可以重新安装下 cnpm install方案二&#xff1a;npm update npm install no…

Error: Program type already present: okhttp3.Authenticator$1

在app中的build.gradle中加入如下代码&#xff0c; configurations {all*.exclude group: com.google.code.gsonall*.exclude group: com.squareup.okhttp3all*.exclude group: com.squareup.okioall*.exclude group: com.android.support,module:support-v13 } 如图 转载于:ht…

3.15 排列对称串

筛选出对称字符串&#xff0c;然后将其排序。 输入样例&#xff1a; 123321 123454321 123 321 sdfsdfd 121212 \\dd\\ 输出样例 123321 \\dd\\ 123454321 #include<fstream> #include<iostream> #include<string> #include<set> using …

ES6规范 ESLint

在团队的项目开发过程中&#xff0c;代码维护所占的时间比重往往大于新功能的开发。因此编写符合团队编码规范的代码是至关重要的&#xff0c;这样做不仅可以很大程度地避免基本语法错误&#xff0c;也保证了代码的可读性&#xff0c;毕竟&#xff1a;程序是写给人读的&#xf…

前端 HTML 常用标签 head标签相关内容 script标签

script标签 定义JavaScript代码 <!--定义JavaScript代码--> <script type"text/javascript"></script> 引入JavaScript文件 src""引入的 js文件路径 <!-- 引入JavaScript文件 --> <script src"./index.js"></s…

3.16 按绩点排名

成绩60分及以上的课程才予以计算绩点 绩点计算公式&#xff1a;[(课程成绩-50) / 10 ] * 学分 学生总绩点为所有绩点之和除以10 输入格式&#xff1a; 班级数 课程数 各个课程的学分 班级人数 姓名 各科成绩 输出格式&#xff1a; class 班级号: 姓名&#xff08;占1…

iview日期控件,双向绑定日期格式

日期在双向绑定之后格式为&#xff1a;2017-07-03T16:00:00.000Z 想要的格式为2017-07-04调了好久&#xff0c;几乎一天&#xff1a;用一句话搞定了 on-change”addForm.Birthday$event”<Date-picker placeholder"选择日期" type"datetime" v-model&…

移除html,jsp中的元素

移除html&#xff0c;jsp中的元素 某些时候&#xff0c;需要移除某个元素&#xff0c;比如移除表中的某一行 $("#tbody").children().eq(i).remove();或者 $("#tr").remove();PS&#xff1a;获取表中的tr的数量&#xff1a; $("#tbody").childre…

ACM001 Quicksum

本题的重点在于数据的读入。 可采用cin.getlin()一行一行读入数据&#xff1b;也可采用cin.get()一个一个读入字符。 cin会忽略回车、空格、Tab跳格。 cin.get()一个一个字符读&#xff0c;不忽略任何字符。 cin.getline()一行一行读入。 #include<fstream> #include…

[Swift]LeetCode884. 两句话中的不常见单词 | Uncommon Words from Two Sentences

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号&#xff1a;山青咏芝&#xff08;shanqingyongzhi&#xff09;➤博客园地址&#xff1a;山青咏芝&#xff08;https://www.cnblogs.com/strengthen/&#xff09;➤GitHub地址&a…

微信公众号 语音录音jssdk

1.开发流程 如果开发的是普通的展示性页面&#xff0c;就和开发普通的页面没有区别&#xff0c;不过这里要用到设备&#xff08;手机&#xff09;的录音功能&#xff0c;就需要调用微信app的录音接口&#xff0c;需要使用微信jssdk。 使用微信jssdk&#xff1a;微信JS-SDK说明文…

iview table 方法若干

新增默认选中1. _checked字段增加2. 给data项设置特殊 key _checked: true2.0 多选框样式错乱&#xff0c;默认选中问题1. 修改为元素checkbox 样式大概调整2. 如果样式不好看 可以自行修改或者使用其他组件ui checkboxAPI props 属性说明类型items显示的结构化数据Arraycolumn…

05 MapReduce应用案例01

1、单词计数 在一定程度上反映了MapReduce设计的初衷--对日志文件进行分析。 public class WordCountMapper extends Mapper<LongWritable, Text, Text, IntWritable>{//该方法循环调用&#xff0c;从文件的split中读取每行调用一次&#xff0c;把该行所在的下标为key&a…

ios高级开发之多线程(一)

1.概念&#xff1a; 多线程&#xff08;multithreading&#xff09;到底是什么呢&#xff0c;它是指在软件或者硬件上实现多个线程并发执行的技术。具有多线程能力的计算机因有硬件的支持&#xff0c;而能够在同一时间执行多个线程&#xff0c;进而提升整体处理性能。在一个程序…

v-if的简单应用

<span v-if"item.status0"> 项目状态&#xff1a;未提交 </span> <span v-if"item.status1"> 项目状态&#xff1a;审批中 </span> <span v-if"item.status2"> 项目状态&#xff1a;审批退回 </span> <s…

05 MapReduce应用案例02

6、統計每個月份中&#xff0c;最高的三個溫度。 輸入格式&#xff1a;年月日 空格 時分秒 TAB 溫度 inputfile: 1949-10-01 14:21:02 34c 1949-10-02 14:01:02 36c 1950-01-01 11:21:02 32c 1950-10-01 12:21:02 37c 1951-12-01 12:21:02 23c 1950-10-…

05 MapReduce应用案例03

8、PageRank Page-rank源于Google&#xff0c;用于衡量特定网页相对于搜索引擎索引中的其他网页而言的重要程度。 Page-rank实现了将链接价值概念作为排名因素。 算法原理 – 入链 投票 • Page-rank 让链接来“ 投票 “ ,到一个页面的超链接相当于对该页投一票。 – 入…

利用微信的weui框架上传、预览和删除图片

jQuery WeUI 是专为微信公众账号开发而设计的一个框架&#xff0c;jQuery WeUI的官网&#xff1a;http://jqweui.com/ 需求&#xff1a;需要在微信公众号网页添加上传图片功能 技术选型&#xff1a;实现上传图片功能可选百度的WebUploader、饿了么的Element和微信的jQuery WeUI…

【转】Java Socket编程基础及深入讲解

原文&#xff1a;https://www.cnblogs.com/yiwangzhibujian/p/7107785.html#q2.3.3 Socket是Java网络编程的基础&#xff0c;了解还是有好处的&#xff0c; 这篇文章主要讲解Socket的基础编程。Socket用在哪呢&#xff0c;主要用在进程间&#xff0c;网络间通信。本篇比较长&am…