- 常量
* 常量应遵循首字母大写的驼峰命名法,同时尽可能言简意赅
如:const PayChannelBank = 1
不建议使用全部大写字母组成,并以下划线分词
如: const PAY_CHANNEL_BANK = 1
* 相关的常量应尽可能的放在一起定义,也可以全部放在 const.go 文件中
- 变量
* 变量命名应遵循驼峰命名法,同时尽可能言简意赅
如:var orderId int64
* 若变量为 `bool` 类型,则名称应以 `has` `is` `can` `allow` 等开头
如: var isExist bool
var hasConflict bool
- 函数与方法
* 函数与方法命名应遵循驼峰命名法,同时尽可能言简意赅
如:func GetOrder(ctx context, orderId int64) (*order, error) {...}
* 若函数或方法为判断类型(返回值主要为 bool 类型),则名称应以 Has, Is, Can 或 Allow 等判断性动词开头
如: func HasPrefix(name string, prefixes []string) bool {...}
func IsEntry(name string, entries []string) bool {...}
* 函数声明应尽可能提高代码利用率
如: func QueryLegalPerson(db *gorm.DB, where map[string]interface{}) ([]*LegalPerson, int32, error)
不建议一种查询条件声明一个方法:
如: func QueryLegalPersonById(db *gorm.DB, id int64) ([]*LegalPerson, int32, error)
- 文件名
* 文件名应全部小写并通过下划线连接,同时尽可能言简意赅
如:bank_pay.go
不建议: bank_pay_service.go
是 service 还是 model 可以通过上层目录判断
- 包名
* 应全部小写。没有大写或下划线
* 大多数使用命名导入的情况下,不需要重命名
* 应简短而简洁,不可用复数,如: net/url,而不是net/urls
- 常量
* 常量声明应尽可能在 /internal/common/const.go 文件中
* 若不在上述文件中,应放在导包之后,定义全局变量之前
- 变量
* 全局变量应放在常量之后,定义结构体之前
* 对于比较重要的局部变量建议通过 `var` 来声明,其他的应尽可能使用 `:=` 短变量声明
* 零值切片可立即使用,无需调用 `make` 创建,如:
var nums []int
if add1 {
nums = append(nums, 1)
}
* 使用字段名初始化结构体,如:
k := User{
FirstName: "John"
}
- 函数与方法
* 入参一定要指定参数名与类型,出参一定不要指定参数名,如:
func PublishPayAccountAddEvt(ctx context.Context, req *proto.CreatePayAccountRecordReq, accountId int64) error
* 对于有error出参函数或方法,一般习惯性将error放在最后一个出参位置,如:
func CreatePayAccount(db *gorm.DB, data map[string]interface{}) (int64, error)
* 函数与函数,方法与方法之间应留一行空白
* 注释应使用//+空格+注释信息,注意描述信息前留空格
* 函数或方法注释,应以函数或方法名开头,并配有描述信息,如:
// OnlinePayment 银企在线支付
func (s *bankPaymentService) OnlinePayment(ctx context.Context, in *proto.OnlinePaymentReq, out *proto.OnlinePaymentRsp) error {...}
* 对于未实现的功能,可以先用 `// TODO 描述信息` 标识,以待后期调整
* 注释要尽可能的言简意赅,避免无意义注释,对于复杂的逻辑可以直接贴tapd需求链接。
* 对于错误日志应统一使用 `log.ErrorS` 记录,其他日志应统一使用 `log.InfoS` 记录
* 对于日志中要打印的复杂参数,尽可能用 `%#v` 格式化输出,如:
log.InfoS(req.GetHead().GetSeq(), "[UpdatePayAccountRecord] rsp[%#v]", rsp.String())
* 错误日志除记录错误信息外,应记录当前方法以及抛出错误的函数或方法,如:
log.ErrorS(seq, "[TransferCallback] models.UpdatePayBatchByBatchNo batch_no: %v, err: %v", batchNo, err)
* 在handle层,每个请求的入参与出参必须要记录日志,如:
log.InfoS(req.GetHead().GetSeq(), "[QueryPayAccountRecord] receive req[%s]", req.String())
log.InfoS(req.GetHead().GetSeq(), "[QueryPayAccountRecord] rsp[%#v]", rsp.String())
* 对于依赖的第三方请求,入参与出参必须要记录日志,如:
log.InfoS(seq, "[TransferBatch] req %v", param)
log.InfoS(seq,"[TransferBatch] rsp %#v", *result)
* 应减少使用 else,可优化成,如:
a := 10
if b {
a = 100
}
* 方法或函数若有返回值,则必须接收。若返回值对业务无关紧要,可以使用`_`忽略,如:
_ = event.PublishPayAccountDeleteEvt(context.Background(), in)
* 文件修改后,必须使用gofmt等工具格式化代码
cmd/ // 入口函数
main.go
dbsql/ // sql备份
tb_pay_order.sql
...
internal/ // 内部服务
common/ // 公共文件目录
common.go // 通用帮助函数
const.go // 常量文件
...
config/ // 配置
config.go // 读取xconf配置并声明全局变量
event/ // 事件
event.go
handle/ // server层
handle.go
...
model/ // 模型层
pay_order.go
...
queue/ // 队列服务
queue.go
...
service/ // service 层
service.go
...
task/ // 定时任务
task.go
...