golang动态实例化解析json
在做mock接口的时候,有几类数据,数据的类型不一样,每类数据是一个json的数组以文件形式保存,使用的时候最好能够根据需求把不同类型的数据混合在一起返回。为了尽量少写代码想着跟python之类的语言一样,使用字符串动态实例化。 例如,有点播数据、直播数据,结构体如下:
// vod 点播数据 type vod struct { ID string `json:"id"` Title string `json:"title"` CommentID string `json:"commentId"` } // live 直播数据 type live struct { ID string `json:"id"` Title string `json:"title"` ChatID string `json:"chatId"` }
动态实例化需要先创建相应的实例的map,然后通过反射获取相应字符串对应结构的类型,然后在实例化对象
var regStruct = make(map[string]interface{ }) regStruct["vod"] = []vod{ } regStruct["live"] = []live{ } var _vodstr = "vod" t := reflect.ValueOf(regStruct[_vodstr]).Type() // 获取对象类型 _vod := reflect.New(t) // 创建实例类型为 *[]vod,使用json.Unmarshal无法直接修改_vod其实例指针的对应指针的值,需要获取到其值所对应的地址 _vodSlice := _vod.Interface() // 获取_vod的实例 json.Unmarshal([]byte(_json),&_vodSlice) // 转化成统一的[]interface{}返回,[]vod直接转成[]interface{}会失败,无法统一转化,需要逐个元素进行转换 var res []interface{ } for i := 0; i < _vod.Elem().Len(); i++ { res = append(res, _vod.Elem().Index(i).Interface()) }
之后把解析好了的数据统一放到一个切片中,随机取其中的部分数据,完成随机生成数据的功能。
// 获取数据 func getData(length int, dataset ...[]interface{ }) []interface{ } { ds := make([]interface{ }, 0) for i := 0; i < len(dataset); i++ { ds = append(ds, dataset[i]...) } res := make([]interface{ }, length) rand.Seed(time.Now().UnixNano()) for i := 0; i < length; i++ { x := rand.Intn(len(ds)) res[i] = ds[x] } return res }
完整mock代码
package main import ( "fmt" "os" "io/ioutil" "encoding/json" "net/http" "math/rand" "time" "reflect" ) type vod struct { ID string `json:"id"` Title string `json:"title"` CommentID string `json:"commentId"` } // live 直播数据 type live struct { ID string `json:"id"` Title string `json:"title"` ChatID string `json:"chatId"` } var ( vs []interface{ } ls []interface{ } regStruct map[string]interface{ } ) // 获取数据 func getData(length int, dataset ...[]interface{ }) []interface{ } { ds := make([]interface{ }, 0) for i := 0; i < len(dataset); i++ { ds = append(ds, dataset[i]...) } res := make([]interface{ }, length) rand.Seed(time.Now().UnixNano()) for i := 0; i < length; i++ { x := rand.Intn(len(ds)) res[i] = ds[x] } return res } // 根据名称预加载数据 func generaterData(name string, file string) []interface{ } { t := reflect.ValueOf(regStruct[name]).Type() _json := reflect.New(t) _jsonSlice := _json.Interface() json.Unmarshal([]byte(read(file)),&_jsonSlice) var res []interface{ } for i := 0; i < _json.Elem().Len(); i++ { res = append(res, _json.Elem().Index(i).Interface()) } return res } func main() { regStruct = make(map[string]interface{ }) regStruct["vod"] = []vod{ } regStruct["live"] = []live{ } vs = generaterData("vod", "./vod.json") ls = generaterData("live", "./live.json") // 从两个的json数据中随机获取6个数据 res := getData(6, vs, ls) fmt.Printlf("Data: %+v", res) }