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)
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章