一、gin框架常用模块
1、基础常用go写法
1)将收到的http post请求中body参数转换为对象
代码语言:javascript复制func UploadConfig(c *gin.Context) {
p := mconfig.CoursewareParam{}
if err := c.ShouldBindJSON(&p); err != nil {
log.Error("发布课件配置body解析报错,错误信息:", err)
comm.SetResultMsg(c, 1, struct{}{}, "解析参数失败!")
return
}
}
- p := mconfig.CoursewareParam{} 的含义是:定义了一个mconfig.CoursewareParam是一个结构体类型,用于存储课件发布的相关配置参数
- c.ShouldBindJSON(&p)的含义是:c.ShouldBindJSON是Gin框架中的一个函数,用于将HTTP请求的JSON格式的请求体解析为Go语言中的结构体对象。第一个参数&p是一个指向CoursewareParam类型变量的指针,用于存储解析后的参数。如果解析失败,函数会返回一个错误对象err,需要进行错误处理。在这段代码中,如果解析失败,会将错误信息打印到日志中,并返回一个自定义的错误信息给客户端。
2)定义map对象的方法
代码语言:javascript复制where := map[string]interface{}{
"lnum": lnum,
"cnum": cnum,
"omo_type": omoType,
}
3) 将json转换为对象
代码语言:javascript复制json.Unmarshal(userres, &user)
这句话是将JSON格式的数据解析为Go语言中的结构体对象。其中,json.Unmarshal是Go语言中的一个函数,用于将JSON格式的数据解析为Go语言中的结构体对象。第一个参数userres是一个byte类型的切片,存储着JSON格式的数据;第二个参数&user是一个指向结构体对象的指针,用于存储解析后的数据。&符号用于获取user变量的地址,因为json.Unmarshal函数需要传入一个指向结构体对象的指针作为参数。
4) 将对象转换为json
代码语言:javascript复制json.Marshal(res)
这句话是将Go语言中的结构体对象转换为JSON格式的数据。其中,json.Marshal是Go语言中的一个函数,用于将Go语言中的结构体对象转换为JSON格式的数据。第一个参数res是一个结构体对象,需要被转换为JSON格式的数据。函数返回一个byte类型的切片,存储着转换后的JSON格式的数据。
5) 将一个包下的userAuth转换为另一个包下的userAuth
代码语言:javascript复制#这个res是第三方包下的UserAuth对象类型
res, err := auth.GetUserInfo(c, key)
if err != nil {
log.Error(err)
return model.UserAuth{}, err
}
#将res对象转换为字节类型的json userres
userres, err := json.Marshal(res)
if err != nil {
log.Error(err)
return model.UserAuth{}, errors.New("获取token失败")
}
#将字节类型json userres转换为model.UserAuth类型的对象
var user model.UserAuth
err = json.Unmarshal(userres, &user)
if err != nil {
log.Error(err)
return model.UserAuth{}, errors.New("获取token失败")
}
其实最后这段代码的作用就是将第三方包下的UserAuth对象类型转换为当前项目下model.UserAuth类型的对象
2、定义变量的两种方法的区别及用法
代码语言:javascript复制p := mconfig.CoursewareParam{} 和 var res *dao.BpCourseware 这两种写法的区别
- 这两种写法的区别在于定义的变量类型不同。第一种写法
p := mconfig.CoursewareParam{}
定义了一个CoursewareParam类型的变量p,并对它进行了初始化。这种写法适用于定义一个具体的变量,可以直接使用该变量进行赋值、传参等操作。第二种写法var res *dao.BpCourseware
定义了一个指向dao.BpCourseware类型的指针变量res,但没有对它进行初始化。这种写法适用于定义一个指针变量,需要在后续的代码中通过new()函数或其他方式对它进行初始化,才能使用该指针变量进行赋值、传参等操作。 - 在后续传参时,两种写法的区别在于传递的值的类型不同。对于第一种写法
p := mconfig.CoursewareParam{}
,p是一个CoursewareParam类型的变量,可以直接将它作为参数传递给需要的函数或方法。对于第二种写法var res *dao.BpCourseware
,res是一个指向dao.BpCourseware类型的指针变量,需要将它的地址作为参数传递给需要的函数或方法。例如,可以通过&res
获取res变量的地址,然后将地址作为参数传递给需要的函数或方法。在函数或方法内部,可以通过*res
获取指针指向的实际数据. - 那么什么时候用第一种,什么时候用第二种呢? 一般来说,使用第一种写法
p := mconfig.CoursewareParam{}
适用于定义一个具体的变量,该变量的类型是已知的,可以直接进行赋值、传参等操作。这种写法比较简洁,代码可读性较高。使用第二种写法var res *dao.BpCourseware
适用于定义一个指针变量,该变量需要在后续的代码中进行初始化,才能使用它进行赋值、传参等操作。这种写法比较灵活,可以在后续的代码中根据需要进行动态的内存分配和释放,但是需要注意指针的生命周期和内存管理,避免出现内存泄漏等问题。
3、go语言单元测试的写法
代码语言:javascript复制func TestSendDingdingNotice(t *testing.T) {
SendDingGroupMsg("哈哈哈")
}
这段代码是Go语言中进行单元测试的写法。其中,func TestSendDingdingNotice(t *testing.T)
定义了一个名为TestSendDingdingNotice的测试函数,用于测试发送钉钉通知的功能。
在Go语言中,测试函数的命名必须以Test开头,并且函数的参数列表中必须包含一个名为t的*testing.T类型的参数。这个参数用于提供测试相关的方法和属性,例如t.Log()用于输出日志信息,t.Errorf()用于输出错误信息等。
在测试函数中,可以编写一些测试用例,用于测试被测试函数的不同输入和输出情况。测试用例通常包括输入数据、期望输出结果和实际输出结果,通过比较期望输出结果和实际输出结果来判断被测试函数是否正确。
这是Go语言中进行单元测试的标准写法
4.go语言中读取配置文件的方法
代码语言:javascript复制比如:要读取dev.ini 配置文件, 或者prod.ini配置文件
我们以单元测试读取配置文件为例说明。
第一步:在单元测试集中指定要读取的配置文件路径
代码语言:javascript复制test.go 单元测试文件
func init() {
# 有一个类Conf,下面有三个属性是Env,IP,Service
entity.Conf.Env = "dev"
entity.Conf.IP, _ = tool.GetNetWorkIpAuto()
entity.Conf.Service = "beibo"
# 初始化日志
log.Initlog()
# 重点:定义了要加载配置文件的方法以及配置文件的路径
LoadConfig("../../dev")
InitRedis()
}
第二步:定义LoadConfig方法读取配置
代码语言:javascript复制config_ini.go文件
// Config结构
type Config struct {
cfg *ini.File
dbCfg *ini.File
}
var WebSwiftEditUrl string
var AppConf Config
func LoadConfig(env string) (err error) {
cfgPath, err := filepath.Abs((env) ".ini")
if err != nil {
log.Error("获取配置文件路径失败", err)
os.Exit(1)
}
cfg, err := ini.Load(cfgPath)
if err != nil {
log.Errorf("Fail to read config: %v, filepath = %s", err, cfgPath)
return err
}
AppConf = Config{cfg: cfg, dbCfg: nil}
if env == "prod" || env == "gray" {
dbPath, err := filepath.Abs("db.ini")
if err != nil {
log.Error("获取配置文件路径失败", err)
os.Exit(1)
}
dbCfg, err := ini.Load(dbPath)
if err != nil {
log.Errorf("Fail to read config: %v, err = %v", dbCfg, err)
return err
}
AppConf.dbCfg = dbCfg
}
entity.Conf.Host = AppConf.Get("host")
entity.Conf.Port = AppConf.Get("httpport")
return nil
}
- 这段代码定义了一个名为Config的结构体类型,该结构体包含两个成员变量:cfg和dbCfg,都是指向ini.File类型的指针。其中,ini.File是一个用于解析INI格式配置文件的结构体类型,包含了INI文件的所有配置信息。通过将INI文件解析为ini.File类型的对象,可以方便地读取和修改INI文件中的配置信息。在这里,Config结构体包含了两个成员变量,分别用于存储两个不同的INI文件的配置信息。
- LoadConfig()方法是用来读取配置文件,根据不同的环境来读取不同的配置文件。最后将读取的文件内容保存在AppConf中。