这是我参与「第三届青训营 -后端场」笔记创作活动的第3篇笔记
前言
在gin项目中,我们都需要将后端信息用json格式响应给前端调用者。 这时候我们可能会封装一个struct作为统一的信息处理。
但是面对格式不一的返回结构,我们就很难用一个struct表达所有类型 比如:
再比如:
前端的请求json格式是多变的,我们无法用一个统一的struct表达它们。这样的话我们就要为每一个请求都写一个struct接收,这样无疑是痛苦的,冗余代码很多
使用反射生成对应的json格式
“办法总比困难多”,我们可以借助golang的反射解决这个问题
思路
- 使用统一的BasicResponse来接收参数
- 将BasicResponse的参数逐个展开,并将其转换为map结构
- 最后将map结构转换为json,响应给前端
代码
func struct2Map(in interface{}) map[string]interface{} {
// 当前函数只接收struct类型
v := reflect.ValueOf(in)
if v.Kind() == reflect.Ptr { // 结构体指针
v = v.Elem()
}
out := make(map[string]interface{}, 8)
queue := make([]interface{}, 0, 1)
queue = append(queue, in)
for len(queue) > 0 {
v := reflect.ValueOf(queue[0])
if v.Kind() == reflect.Ptr { // 结构体指针
v = v.Elem()
}
queue = queue[1:]
t := v.Type()
for i := 0; i < v.NumField(); i++ {
vi := v.Field(i)
if vi.Kind() == reflect.Interface { // interface; data部分
queue = append(queue, vi.Interface())
break
}
// 一般字段
ti := t.Field(i)
if tagValue := ti.Tag.Get("json"); tagValue != "" {
// 存入map
out[tagValue] = vi.Interface()
}
}
}
return out
}