快捷搜索: 王者荣耀 脱发

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)
}
经验分享 程序员 微信小程序 职场和发展