学习一门语言,首先要了解该语言的代码编程规范,以提高代码的可读性、规范性。
一、 命名规范
同其他编程语言一样,go语言命名可以由字母、数字和下划线组成,并且不能以数字开头。go语言命名区分大小写。
note:当命名以大写字母开头时,可以被外部包的代码使用,以小写字母开头,则对外部包不可见。
1、包命名:package
【shall】包名必须全部小写,无下划线,简短,见名知义。尽量不要与标准库重名,禁止通过中划线连接多个单词。
【should】尽量和目录名保持一致。
package main
package student
2、 文件命名
【shall】文件名使用小写单词,可以使用下划线分割各个单词,但是头尾不能为下划线。
【should】文件名虽然允许出现下划线,但是尽量避免。文件名尽量简短,见名知义。
my_utils.go
3、变量命名
【shall】变量命名采用大小写驼峰法命名,不允许使用下划线。
- 特有名词开头在私有的情况下,使用小写,如
urlArray
- 特有名词开头在公开的情况下,使用小写,如
URLArray
- 若变量类型为bool,则命名应以
Has
,Is
,Can
,Allow
开头,如isExit
4、常量命名
【shall】常量&枚举名,大小写驼峰法,不允许下划线,第三方包例外
const AppEnv = "1.0"
5、 结构体命名
【shall】结构体名必须为大小写混排的驼峰模式,不允许出现下划线,首字母根据访问控制大写或者小写
【should】结构名建议采用名词、动名词,struct 申明和初始化格式采用多行,例如下面:
// 多行申明
type User struct{
Username string
Email string
}
// 多行初始化
u := User{
Username: "astaxie",
Email: "[email protected]",
}
6、 接口命名
【shall】接口名必须为大小写混排的驼峰模式,不允许出现下划线,首字母根据访问控制大写或者小写,整体必须为名词。
【should】单个函数的结构名以 “er” 作为后缀,例如 Reader , Writer 。
type Reader interface {
Read(p []byte) (n int, err error)
}
7、函数&方法名
【shall】函数名必须为大小写混排的驼峰模式,首字母根据访问控制大写或者小写。
【should】函数名力求精简准确,并采用动词或动词短语。
func MakeRegexpArrayOrDie(){} // 包外可访问
func matchesRegexp(){} // 包内访问
【shall】方法接收者命名必须为大小写混排,首字母小写。方法接收者命名要能够体现接收者对象。
【should】方法接收者命名通常1个或者2个字母就够,最长不能超过4个字母。
【should】方法接收者命名不要使用me,this 或者 self 这种泛指的名字。
func (c *Controller) Run(){}
8、 参数和返回值命名
【should】参数名和返回值命名必须为大小写混排的驼峰模式,且首字母小写,不能有下划线。
func getAge(studentName string)(age int){}
二、注释规范
Go提供C风格的/* */
块注释和C ++风格的//
行注释。行注释更加通用;块注释主要用于针对包的详细说明或者屏蔽大块的代码。
1、包注释
- 每个包都应该有一个包注释,一个位于package子句之前的块注释或行注释。
- 包注释应该包含下面基本信息(简介,创建人,创建时间)
例如 util 包的注释示例如下
// util 包, 这是一个公共函数的工具包
// 创建人: 姑姑
// 创建时间: 20200816
2、结构&接口注释
每个自定义的结构体或者接口都应该有注释说明,该注释对结构进行简要介绍,放在结构体定义的前一行,格式为: 结构体名, 结构体说明。同时结构体内的每个成员变量都要有说明,该说明放在成员变量的后面(注意对齐),实例如下:
// User , 用户对象,定义了用户的基础信息
type User struct{
Username string // 用户名
Email string // 邮箱
}
3、函数(方法)注释
每个函数或者方法都应该有注释说明,函数的注释应该包括三个方面(严格按照此顺序撰写):
- 简要说明,格式说明:以函数名开头,“,”分隔说明部分
- 参数列表:每行一个参数,参数名开头,“,”分隔说明部分
- 返回值: 每行一个返回值
示例如下:
// NewtAttrModel , 属性数据层操作类的工厂方法
// 参数:
// ctx ,上下文信息
// 返回值:
// 属性操作类指针
func NewAttrModel(ctx *common.Context) *AttrModel {
}
4、代码逻辑注释
对于一些关键位置的代码逻辑,或者局部较为复杂的逻辑,需要有相应的逻辑说明,方便其他开发者阅读该段代码,实例如下:
// 从 Redis 中批量读取属性,对于没有读取到的 id ,
// 记录到一个数组里面,准备从 DB 中读取
xxxxx
xxxxxxx
xxxxxxx
5、注释风格
统一使用中文注释,对于中英文字符之间严格使用空格分隔, 这个不仅仅是中文和英文之间,英文和中文标点之间也都要使用空格分隔,例如:
// 从 Redis 中批量读取属性,对于没有读取到的 id ,
// 记录到一个数组里面,准备从 DB 中读取
上面 Redis 、 id 、 DB 和其他中文字符之间都是用了空格分隔。
- 建议全部使用单行注释
- 和代码的规范一样,单行注释不要过长,禁止超过 120 字符。
三、代码风格
1、缩进和折行
- 缩进直接使用 gofmt 工具格式化即可(gofmt 是使用 tab 缩进的);
- 折行方面,一行最长不超过120个字符,超过的请使用换行展示,尽量保持格式优雅。
2、语句的结尾
Go语言中是不需要类似于Java需要冒号结尾,默认一行就是一条数据
如果你打算将多个语句写在同一行,它们则必须使用 ;
3、括号和空格
括号和空格方面,也可以直接使用 gofmt 工具格式化(go 会强制左大括号不换行,换行会报语法错误),所有的运算符和操作数之间要留空格。
// 正确的方式
if a > 0 {
}
// 错误的方式
if a>0 // a ,0 和 > 之间应该空格
{ // 左大括号不可以换行,会报语法错误
}
4、import 规范
import在多行的情况下,goimports会自动帮你格式化,但是我们这里还是规范一下import的一些规范,如果你在一个文件里面引入了一个package,还是建议采用如下格式:
import (
"fmt"
)
如果你的包引入了三种类型的包,标准库包,程序内部包,第三方包,建议采用如下方式进行组织你的包:
import (
"encoding/json"
"strings"
"myproject/models"
"myproject/controller"
"myproject/utils"
"github.com/astaxie/beego"
"github.com/go-sql-driver/mysql"
)
有顺序的引入包,不同的类型采用空格分离,第一种实标准库,第二是项目包,第三是第三方包。
在项目中不要使用相对路径引入包:
// 这是不好的导入
import “../net”
// 这是正确的做法
import “github.com/repo/proj/src/net”
但是如果是引入本项目中的其他包,最好使用相对路径。
5、错误处理
- 错误处理的原则就是不能丢弃任何有返回err的调用,不要使用 _ 丢弃,必须全部处理。接收到错误,要么返回err,或者使用log记录下来
- 尽早return:一旦有错误发生,马上返回
- 尽量不要使用panic,除非你知道你在做什么
- 错误描述如果是英文必须为小写,不需要标点结尾
- 采用独立的错误流进行处理
// 错误写法
if err != nil {
// error handling
} else {
// normal code
}
// 正确写法
if err != nil {
// error handling
return // or continue, etc.
}
// normal code
6、测试
单元测试文件名命名规范为 example_test.go
测试用例的函数名称必须以 Test 开头,例如:TestExample
每个重要的函数都要首先编写测试用例,测试用例和正规代码一起提交方便进行回归测试